假设我有
e1 :: Event t A
f :: A -> IO B
我想创建
e2 :: Event t B
它由 触发e1
,其值是通过在事件发生时f
对 的值执行来确定的。e1
我看到了两种可能的方法来做到这一点,通过动态事件切换和使用处理程序,但对于这么简单的事情来说,它们看起来都太复杂了。
这样做的正确方法是什么?
假设我有
e1 :: Event t A
f :: A -> IO B
我想创建
e2 :: Event t B
它由 触发e1
,其值是通过在事件发生时f
对 的值执行来确定的。e1
我看到了两种可能的方法来做到这一点,通过动态事件切换和使用处理程序,但对于这么简单的事情来说,它们看起来都太复杂了。
这样做的正确方法是什么?
既然函数f
有副作用,这其实不是一件简单的事情。主要原因是当有多个同时发生的事件时,副作用的顺序没有明确定义。更一般地说,我无法设想一个好的语义来处理事件中的 IO 动作。因此,reactive-banana 没有为这种情况提供一个纯粹的组合子。
如果您无论如何都想这样做,则必须使用更复杂的机制,该机制也决定了副作用的顺序。例如,您可以使用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
。例如,行为可能已经改变并且可能已经执行了其他副作用。
你能调用函数吗(据我所知,这是处理来自事件网络的 IO 的“正确方法”)f
?reactimate
从那里,Event t B
向事件网络触发一个类型的新事件。或者这就是你所说的“使用处理程序”?