我正在使用reactive-banana开发一个程序,我想知道如何使用基本的 FRP 构建块来构建我的类型。
例如,这是我真实程序中的一个简化示例:假设我的系统主要由小部件组成——在我的程序中,是随时间变化的文本片段。
我本可以有
newtype Widget = Widget { widgetText :: Behavior String }
但我也可以
newtype Widget = Widget { widgetText :: String }
并Behavior Widget
在我想谈论随时间变化的行为时使用。这似乎让事情变得“更简单”,并且意味着我可以Behavior
更直接地使用操作,而不必解包和重新打包小部件来完成它。
另一方面,前者似乎避免了实际定义小部件的代码中的重复,因为几乎所有小部件都随时间而变化,而且我发现自己甚至定义了少数不带的小部件Behavior
,因为它让我可以将它们与其他人以更一致的方式。
另一个例子,对于这两种表示,有一个实例是有意义的Monoid
(我想在我的程序中有一个),但后者的实现似乎更自然(因为它只是将 list monoid 提升到 newtype )。
(我的实际程序使用Discrete
而不是Behavior
,但我认为这无关紧要。)
同样,我应该使用Behavior (Coord,Coord)
还是(Behavior Coord, Behavior Coord)
表示 2D 点?在这种情况下,前者似乎是显而易见的选择;但当它是代表游戏中实体之类的五元素记录时,选择似乎不太明确。
本质上,所有这些问题都归结为:
使用 FRP 时,我应该在哪一层应用Behavior
类型?
(同样的问题也适用Event
,尽管程度较轻。)