我已经阅读了 netwire quickstart,但我无法想象整个事物在“真实”应用程序中的样子。由于本教程仅涉及纯电线,因此我对游戏特别感兴趣,如果有的话,但我不介意其他人。Reactive Banana 示例可能也可以。他们应该只是说明 FRP 是如何有用的。
2 回答
Netwire 在一些现实世界的应用程序中使用,但我不知道在哪里可以找到它们。他们可能目前处于闭门状态。但是,Reddit 上已经发布了一些示例应用程序,因此您可能需要查看/r/haskell。只需在那里搜索“netwire”。不幸的是,响应式香蕉示例无济于事,因为这两个库的概念,尤其是事件处理的概念完全不同。
Netwire 应用程序的总体结构是这样的:首先定义一个反应值,我们称之为simulation
。在最简单的情况下,它是纯线:
simulation :: WireP a [Particle]
在没有详细说明(尚未)如何编写该线的情况下,让我现在解释一下它是什么。输出类型是[Particle]
,所以它是粒子的反应列表。这意味着,此列表可能会随着时间而改变。值得注意的是输入类型是完全多态的,所以你知道这个反应值不依赖于其他反应值。
现在您想要获取粒子列表在特定时间点的实际值。这就是你的会话和步进函数的用武之地。大多数应用程序只需要像stepSessionP
这种情况下的会话步进函数之一。您只需在循环中调用此函数即可获取此时导线的当前值。无需连续调用此函数。
你会注意到步进函数没有给你 a [Particle]
,而是 a Either LastException [Particle]
。这是因为 Netwire 中的无功值可以抑制. 这就是事件概念。你从范畴法则知道
w . id
与 相同 与 几乎w
相同x + 0
与 相同x
。标识线相对于 是中性的(.)
。然而,现在想象
w . myId
wheremyId
就像身份线一样,只是产生它所依赖的任何反应值,但有时它根本不会产生。有时它会忽略该值而只是抑制,在这种情况下,组合本身会抑制。您可以将其解释myId
为事件连线,并将组合读取为“ w
if myId
”:
w . keyDown Space
然后你有你的选择运算符(<|>)
,它就像事件的“或”:
w1 . ev1 <|> w2 . ev2 <|> w3
如果ev1
抑制,则尝试其余的。理想情况下,主线永远不会抑制,因此您可以使用stepSessionP_
它,但它由潜在的抑制线组成。你也可以使用你自己的抑制幺半群来产生退出信号之类的东西。
对于那些在未来偶然发现这一点的人,我认为这是使用 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