Ech*_*lan 5 haskell frp netwire
我正在使用Netwire编写一个由来自网络的事件驱动的程序.我想这里有三个问题:
是什么让人Control.Wire.Unsafe.Event不安全?就像标题所说,我需要保持哪些不变量才能安全使用它?
我觉得我需要这样的东西:mapMaybeE :: Monad m => (a -> Maybe b) -> Wire s e m (Event a) (Event b).上下文是我有来自网络的消息,我想只响应其中一些消息.这就是我写的:
mapMaybeE :: Monad m => (a -> Maybe b) -> Wire s e m (Event a) (Event b)
mapMaybeE f = arr go . arr (fmap f)
where go WU.NoEvent = WU.NoEvent
go (WU.Event Nothing) = WU.NoEvent
go (WU.Event (Just a)) = WU.Event a
Run Code Online (Sandbox Code Playgroud)
这是"合法的"吗?或者如果没有事件,我是否应该禁止?
Netwire对这类问题有意义吗?我见过的所有例子都是不断循环的游戏.在这里,我只想在有事情要做的时候踩电线.大多数情况下,这将是网络事件,但我可能也想在计时器上做事情.例如,一个事件进入,然后五秒钟后程序执行某些操作.它不应该连续循环,直到会话中的时间比事件进入的时间大5秒.
对于其中许多答案,“正确”或“合法”取决于您希望应用程序执行的操作。“惯用”可能是一个更有趣的问题,但由于图书馆作者已经去世,很难明确地回答这些问题。因此,以下内容仅代表我的经验,可能不正确:
“不安全”部分Control.Wire.Unsafe.Event是这样的想法:您将及时处理离散实例,并且您可能不一定保留程序期望的连续时间语义。特别是,在模拟中发生的事件与表示为 an和 a 的时间状态( in s)之间没有区别(从类型的角度来看) ,因此您必须小心确保您正在做的事情使对您的应用程序有意义。所包含的通用组合器不存在这种风险,因为它们与“时间”的任何合理定义一起工作。来自以下文档:Wire s e m a bIntegerFloatdata Event
表示值流,每个值都与发生时间一起。由于事件通常用于函数反应式编程,因此它没有定义大多数常用实例来保护连续时间和离散事件发生语义。
来自自述文件:
如果您是框架开发人员,您可以导入
Control.Wire.Unsafe.Event模块来实现您自己的事件。游戏引擎可能包括按键事件或场景中发生的某些事情。但是,作为应用程序开发人员,您应该将这种类型视为不透明。为了保护连续时间语义,这是必要的。您无法直接访问事件值。
这样做当然没有什么“违法”之处。当你抑制完全取决于你的应用程序。关键的区别在于,如果您编写抑制的连线,则抑制会“冒泡”到处理它的第一条连线(例如使用Alternative: (<|>))。NoEvent如果没有事件,制作就很好。:) 您正在寻找的行为可能可以使用现有的组合器更好地建模dropWhileE,并且fmap可以Control.Wire.Event:
mapMaybeE :: Monad m => (a -> Maybe b) -> Wire s e m (Event a) (Event b)
mapMaybeE = arr (fmap fromJust) . dropWhileE isNothing . arr (fmap f)
Run Code Online (Sandbox Code Playgroud)是的,netwire对于必须模拟具有时间相关语义的系统状态的任何问题都是有意义的。扩大,
它不必连续循环,直到会话中的时间比事件进入时长五秒。
需要有一些东西来跟踪这个计时器,所以你将无法避免以一种或另一种能力存在循环。(也许您可以让操作系统通过调用sleep或其他方式来完成此操作,但内部某处仍然存在一些循环...)netwire让您可以显式地对系统的行为进行建模并响应这些类型的事件:网络事件和计时器事件。因为 Haskell 很懒惰,所以如果您编写连线,使得“真正复杂的连线”依赖于计时器,那么在计时器到期之前不会评估“真正复杂的连线”的结果(请参阅 参考资料after)。
| 归档时间: |
|
| 查看次数: |
68 次 |
| 最近记录: |