Reactive的Monad实例如何处理并发事件?

时间:2019-06-30 19:46:53

标签: haskell frp

在Conal Elliot的Push-Pull Functional Reactive Programming中,在第7.1.3节中为Reactive提供了一个Monad实例。如果join的内部和外部反应堆同时起火怎么办?

never :: Event a
MkFuture :: Time -> a -> Future a
pure :: a -> Future a -- at time zero
MkReactive :: a -> Event a -> Reactive a
MkEvent :: Future (Reactive a) -> Event a

join (MkReactive (MkReactive "foo" never) (MkEvent (pure (MkReactive "bar" never)))

应该忽略"foo"还是将其包含在联接结果中?

1 个答案:

答案 0 :(得分:1)

这是第7.1.3节中的join定义(略述):

-- urr is the outer Reactive; ur is the inner one.
joinR :: Reactive (Reactive a) -> Reactive a
joinR ((a `Stepper` Ev ur) `Stepper` Ev urr) = a `Stepper` Ev u
    where
    u = ((`switcher` Ev urr) <$> ur) <> (join <$> urr)

Monoid的定义中使用的u实例是Future的实例,在第4.5节中定义,在同时触发的情况下,选择左实例。这样一来,如果join中同时触发,则内部触发不会被丢弃。对于您问题中的特定示例,在零时间采样仍应给出"foo"。 (我认为,如果不是这种情况,将违反单子法join . fmap return = id