如何使用IO函数转换事件?

时间:2013-06-23 12:05:30

标签: haskell frp reactive-banana

假设我有

e1 :: Event t A
f  :: A -> IO B

我想创建

e2 :: Event t B

e1触发,其值是通过在事件发生时对f的值执行e1来确定的。

我看到了两种可能的方法,通过动态事件切换和使用处理程序,但它们看起来都太复杂了,无法做到这么简单。

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

由于函数f有副作用,这实际上并不是一件简单的事情。主要原因是当存在多个同时发生的事件时,副作用的顺序没有明确定义。更一般地说,我无法想象在事件中处理IO动作的良好语义。因此,反应性香蕉不能为这种情况提供纯粹的组合剂。

如果你想要这样做,你必须使用更复杂的机制,也决定副作用的顺序。例如,您可以使用reactimate并编写组合器

mapIO :: Frameworks t => (a -> IO b) -> Event t a -> Moment t (Event t b)
mapIO f e1 = do
    (e2, fire2) <- liftIO newAddHandler
    reactimate $ (\x -> f x >>= fire2) <$> e1
    fromAddHandler e2

但请注意,这可能会产生意外结果,因为结果事件e2不再与输入事件e1同时发生。例如,行为可能已经改变,并且可能已经执行了其他副作用。

答案 1 :(得分:1)

你可以在f中调用函数reactimate(根据我的理解,这是从事件网络处理IO的“正确方法”)吗?从那里,向事件网络发起类型为Event t B的新事件。或者这就是“使用处理程序”的意思吗?