haskell - Conal Elloit 的 FRP 中的 Reactive 的 Monad 和 Applicative 实例

标签 haskell frp

Conal Elliott's paper具有以下定义:

Future a = (Time, a)
Stepper :: a -> Event a -> Reactive a
Ev :: Future (Reactive a) -> Event a
never : Event a
instance Monad Reactive
rA :: Reactive String
rA = "IA" `Stepper` (Ev (1, "1A" `Stepper` never))

rB :: Reactive String
rB = "IB" `Stepper` (Ev (1, "1B" `Stepper` never))

rC1 :: Reactive String
rC1 = (++) <$> rA <*> rB
rC1 = "IAIB" `Stepper` (Ev (1, "IA1B" `Stepper` never))

我相信以上是正确的。

rC2 :: Reactive String
rC2 = rA >>= (\a -> (a++) <$> rB)

应该rC1 = rC2

根据论文中的定义,"IA1B" and "1AIB"将包含在 "IAIB" 之间和"1A1B"rC2 .

这不违反 Monad 定律 (<*>) = ap ?不应该rC1 = rC2 ?或者我误解了什么。

Here is the Idris code I am using

最佳答案

这个故事有两个错误。问题给出的例子实际上只暴露了第一个,但是在研究它的过程中,我发现 join 的定义中存在另一个更严重的错误。 .

第一个错误很小:它与处理同时发生的事件有关。您的race功能允许您合并同时发生的事件。 (<*>) 中利用了这一点。 ,但是在 join 的定义中,These case 假装左侧(内部)事件首先发生。因此,如果您考虑实现 (<*>)使用join ,并且这两种行为具有同时发生的事件,join不会合并它们。

在 react 行为的情况下,两个同时发生的事件与两个在时间上非常接近发生的事件无法区分,并且无论如何,最后一个事件获胜,因此前一个事件是否出现在事件中并不重要流或不流。例如,如果您开始对事件进行计数,这种情况就会崩溃,因此我会简单地得出结论,不应在行为上允许进行此类操作。

我认为=法律中出现的符号通常在语法上被采用得太过(如果你允许我这样调用它的话),而在很多情况下,比如这个,从语义上理解它会更灵活。它们通常是一致的,因此除非您习惯于正式思考,否则很难真正理解这一点。

从这个角度来看,将其视为“不是错误”而忽略它是合理的。似乎仍然有可能修复实现,以便法律在语法上确实成立;无论如何,这会让每个人都高兴。


要理解第二个错误,您必须再看一下join :: Reactive (Reactive a) -> Reactive a的含义。 .

一个r :: Reactive (Reactive a)是一种不断发展的行为。有时你会得到行为 x (其内部变化未显示),则行为 y ,然后行为z ...从原理上讲,它看起来像一个行为流

xxxxx...
yyyyy...
zzzzz...
...

如果我们将行为视为时间的函数 r :: Time -> (Time -> a) , join sample r当时t ,这是另一种行为 r t :: Time -> a ,其本身在时间 t 进行采样:(join r) t = r t t 。换句话说,您采取对角线行为:

x
 y
  z

因此,如果我们回顾 Reactive 的事件驱动定义,一旦出现新行为,忘记事件是很自然的。事实上, join 的定义正如论文中所示,通过与 join <$> urr 比赛来做到这一点,它忘记了内部行为 ur 。然而,这只占对角线的一侧:

x
yy
zzz

因为Reactive行为是事件流,Reactive (Reactive a) 的内部流。可以包含流自身出现之前发生的事件。因此,当你得到 Future (Reactive a) ,您还需要一种方法来截断 Future 之前的事件发生:

actualize :: Future (Reactive a) -> Future (Reactive a)
-- Exercise for the reader

并在join中的某个地方使用它.

关于haskell - Conal Elloit 的 FRP 中的 Reactive 的 Monad 和 Applicative 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57080085/

相关文章:

haskell - Hasql:编码和类型

javascript - 使用 baconjs 输出项目列表

javascript - bacon.js - 获取流/属性的值

ios - 动态改变 throttle 参数

haskell - 有什么解决方法可以在 Data.Dynamics 中获取多态函数吗?

haskell - 堆栈项目中缺少 ghc-mod 包

haskell - 实现 zipE::Event t a -> 事件 t b -> 事件 t (a,b)

haskell - 我使用的是 react 香蕉吗?

haskell - 在处理许多不相关的类型时避免样板

haskell - Setter 保留索引是什么意思?