【发布时间】:2014-05-07 01:27:39
【问题描述】:
为了自己的兴趣,我正在尝试实现一个简单的 FRP 后端。
我决定使用纯函数:所以,核心中没有 IO。该实现基于信号变压器。
我已经尝试了两种方法:
newtype SF a b = SF { listen :: [a] -> [b] }
https://gist.github.com/Heimdell/9675964#file-streamer-hs-L1
和
newtype SF a b = SF { run :: a -> (b, SF a b) }
https://gist.github.com/Heimdell/9675964#file-behaviour-hs-L1(命名错误,抱歉)
这两种方法都可以使 fold/integrate :: (a -> b -> b) -> b -> SF a b 组合器用于信号集成。
两种方式都有问题:似乎不可能生成有效的 ArrowApply/Monad 实例。
-
Stream-way:我们有一个列表对
(arrow, x)- 或者,unziped,列表对(arrows, xs)。- 如果我们将
map head转换为zipWith ($)'em 的结果,我们将失去携带箭头突变。 - 如果我们让
head arrows监听xs,我们将冻结第一个箭头的状态。
- 如果我们将
-
显式状态方式:
instance ArrowApply Behaviour where app = Behaviour $ \(bf, a) -> let (bf1, c) = bf `runBehaviour` a in (app, c)这里我们需要以某种方式有效地将
bf1注入返回的app,这是不可能的(实际上由(const bf1 *** id)注入会产生类似于其他实现的第二个无效行为。
有没有一种可能的方法来创建一个允许 ArrowApply 实例的SF?
P.S.:当分支长时间未使用时,流路在 ArrowChoice 中存在内存泄漏。目前,我无法解决这个问题。是否有可能制作它的无泄漏版本?
P.P.S:如果需要时间,他可以用输入压缩它。
【问题讨论】:
-
对于第二种类型
newtype SF a b = SF { run :: a -> (b, SF a b) },您可能会注意到Monad实例总是会在每个事件的内部和外部容器中引发a事件。因此,内容器的状态将无关紧要。 -
您可能还对 J. Abrahamson 关于在 FRP 中实现
join的问题感兴趣:stackoverflow.com/questions/20890439/behavior-now-in-frp/… -
我的印象是,当您根本无法创建一个明智的
ArrowApply/Monad实例时,箭头会特别亮。
标签: haskell frp stateful purely-functional