14

我已经阅读了 netwire quickstart,但我无法想象整个事物在“真实”应用程序中的样子。由于本教程仅涉及纯电线,因此我对游戏特别感兴趣,如果有的话,但我不介意其他人。Reactive Banana 示例可能也可以。他们应该只是说明 FRP 是如何有用的。

4

2 回答 2

14

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为事件连线,并将组合读取为“ wif myId”:

w . keyDown Space

然后你有你的选择运算符(<|>),它就像事件的“或”:

w1 . ev1 <|> w2 . ev2 <|> w3

如果ev1抑制,则尝试其余的。理想情况下,主线永远不会抑制,因此您可以使用stepSessionP_它,但它由潜在的抑制线组成。你也可以使用你自己的抑制幺半群来产生退出信号之类的东西。

于 2013-02-09T14:55:24.733 回答
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/

于 2013-09-04T20:06:04.060 回答