我已经阅读过netwire quickstart,但我在设想“真实”应用程序中整个事物的样子时遇到了问题。因为教程只涉及纯线,所以我对游戏特别感兴趣,但是我不介意别人。反应性香蕉的例子可能也会这样。他们应该只说明FRP是如何有用的。
答案 0 :(得分:14)
Netwire用于某些实际应用程序,但我不知道在哪里可以找到它们。可能他们目前闭门造车。但是,一些示例应用程序已在Reddit上发布了博客,因此您可能需要查看/r/haskell。只需在那里搜索“netwire”。不幸的是,反应性香蕉的例子无济于事,因为这两个库的概念,尤其是事件处理的概念完全不同。
Netwire应用程序的整体结构如下:首先定义一个无功值,让我们称之为simulation
。在最简单的情况下,它是纯粹的电线:
simulation :: WireP a [Particle]
如果没有详细说明(还)如何编写那根电线让我现在解释它是什么。输出类型为[Particle]
,因此它是一个反应性粒子列表。这意味着,此列表可能会随时间而变化。值得注意的是输入类型是完全多态的,因此您知道此无效值不依赖于其他反应值。
现在,您希望在特定时间点获取粒子列表的实际值。这是您的会话和步进功能的用武之地。在这种情况下,大多数应用程序只需要一个会话步进功能,如stepSessionP
。您只需在循环中调用此函数即可获得此时的线的当前值。无需连续调用此功能。
您会注意到,步进功能不会为您提供[Particle]
,而是Either LastException [Particle]
。这是因为Netwire中的反应值可以禁止。这是事件概念。你从类别法中知道
w . id
与w
仅相同,x + 0
与x
相同。身份线相对于(.)
是中性的。但是,现在想象
w . myId
其中myId
的作用类似于标识线,只会导致它所依赖的任何无效值,但有时它根本不会产生结果。有时它忽略了价值而只是抑制,在这种情况下,组合物本身会抑制。您可以将myId
解释为事件摘要,并将合成内容读作“w
myId
”:
w . keyDown Space
然后你有了你的选择算子(<|>)
,它的作用类似于事件的“或”:
w1 . ev1 <|> w2 . ev2 <|> w3
如果ev1
禁止,则尝试其余部分。理想情况下,主线永远不会抑制,因此您可以使用stepSessionP_
代替,但它由潜在的抑制线组成。你也可以使用自己的抑制monoid来戒掉信号。
答案 1 :(得分:7)
对于那些在将来偶然发现这一点的人,我认为这是使用netwire完整应用程序的一个很好的例子。他也开始(截至今天)也在PACMAN工作。
http://www.reddit.com/r/haskell/comments/1kmes7/building_an_asteroids_clone_in_haskell_using/
http://ocharles.org.uk/blog/posts/2013-08-18-asteroids-in-netwire.html