我正在教自己FRP和Reactive-banana,同时写下我希望对跟随我的人更有用的教程。您可以在教程here上查看我的进度。
我一直试图使用事件来实现简单的嘟嘟噪声示例。我知道我需要做这样的事情:
reactimate $ fmap (uncurry playNote) myEvent
在我的NetworkDescription
中,但我无法弄清楚如何让网络反复做同样的事情,或者做一次事情。理想情况下,我正在寻找这样的事情:
once :: a -> Event t a
repeatWithDelay :: Event t a -> Time -> Event t a
concatWithDelay :: Event t a -> Event t a -> Time -> Event t a
上面的Time
类型只是我们最终使用的任何时间测量的替身。我是否需要将系统时间作为行为来连接以驱动“延迟”功能?这似乎比必要的更复杂。
提前致谢,
Echo Nolan
编辑:好的,repeatWithDelay和concatWithDelay的类型没有意义。这就是我的意思。
repeatWithDelay :: a -> Time -> Event t a
concatWithDelay :: a -> a -> Time -> Event t a
答案 0 :(得分:4)
我之前选择不在核心模型中包含此类功能,因为 time 会对一致性提出各种挑战。例如,如果两个事件计划在5秒后发生,那么它们应该同时进行吗?如果没有,哪一个应该先来?我认为核心模型应该适合于形式证明,但这不适用于实际的物理时间测量。
那就是说,我打算将这些功能纳入“他们工作,但不能保证”的时尚。我还没有这样做的主要原因是没有时间测量的正常选择。不同的应用程序有不同的需求,有时您需要纳秒级的分辨率,有时您希望使用GUI框架中的计时器,有时您希望同步到外部MIDI时钟。换句话说,您希望基于时间的函数在许多计时器实现中一般工作,并且只有使用reactive-banana-0.7.0才能找到一个很好的API设计。
当然,使用定时器已经可以实现自己的基于时间的功能。 Wave.hs示例演示了如何执行此操作。另一个例子是Henning Thielemann的reactive-balsa library,它实现了各种基于时间的组合器来实时处理MIDI数据。