我已经阅读了netwire 快速入门,但我在设想整个事物在"真实"应用程序中的样子时遇到了问题.因为教程只涉及纯线,所以我对游戏特别感兴趣,但是我不介意别人.反应性香蕉的例子可能也会这样.他们应该只说明FRP如何有用.
ert*_*tes 14
Netwire用于一些实际应用程序,但我不知道在哪里可以找到它们.可能他们目前闭门造车.但是,一些示例应用程序已经在Reddit上发布了博客,因此您可能需要查看/ r/haskell.只需在那里搜索"netwire".不幸的是,反应性香蕉的例子无济于事,因为这两个库的概念,尤其是事件处理的概念完全不同.
Netwire应用程序的整体结构如下:首先定义一个无功值,让我们调用它simulation.在最简单的情况下,它是纯粹的电线:
simulation :: WireP a [Particle]
Run Code Online (Sandbox Code Playgroud)
如果没有详细说明如何编写那根电线,我现在就解释它是什么.输出类型是[Particle],因此它是一个反应性的粒子列表.这意味着,此列表可能会随时间而变化.值得注意的是输入类型是完全多态的,因此您知道此反应值不依赖于其他反应值.
现在,您希望在特定时间点获取粒子列表的实际值.这是您的会话和步进功能的用武之地.大多数应用程序只需要一个会话步进功能,如stepSessionP本例所示.您只需在循环中调用此函数即可获得此时的线的当前值.无需连续调用此功能.
你会注意到步进功能不会给你一个[Particle],但是a Either LastException [Particle].这是因为Netwire中的反应值可以抑制.这是事件概念.你从类别法律中知道了
w . id
Run Code Online (Sandbox Code Playgroud)
就像w大致相同的方式x + 0一样x.身份线相对于中性线是中性的(.).但是,现在想象一下
w . myId
Run Code Online (Sandbox Code Playgroud)
其中的myId行为就像身份线一样,只会导致它所依赖的任何反应值,但有时它根本不会产生.有时它忽略了价值而只是抑制,在这种情况下,组合物本身会抑制.您可以将其解释myId为事件连线并将组合作为" wif myId" 读取:
w . keyDown Space
Run Code Online (Sandbox Code Playgroud)
然后你有你的选择运算符(<|>),它对事件的作用类似于"或":
w1 . ev1 <|> w2 . ev2 <|> w3
Run Code Online (Sandbox Code Playgroud)
如果ev1抑制,则尝试其余部分.理想情况下,主线永远不会抑制,因此您可以使用stepSessionP_,但它由潜在的抑制线组成.你也可以使用自己的抑制monoid来戒掉信号.
小智 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
https://github.com/ocharles/netwire-classics/