假设我有
e1 :: Event t A
f :: A -> IO B
我想创建
e2 :: Event t B
由e1
触发,其值是通过在事件发生时对f
的值执行e1
来确定的。
我看到了两种可能的方法,通过动态事件切换和使用处理程序,但它们看起来都太复杂了,无法做到这么简单。
这样做的正确方法是什么?
答案 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
的新事件。或者这就是“使用处理程序”的意思吗?