经过一些试验,我已经实现了我需要的行为。基本上,您编写了一个自定义抑制剂类型,它可以捕获您需要的事件概念。就我而言,它是
data Inhibitor = Done | Timeout | Interrupt deriving Show
完成意味着正常完成,其余构造函数发出某种错误信号。
之后,您编写所需的任何自定义组合器。就我而言,我需要一种方法来停止计算并进一步发出错误信号:
timeout deadline w | deadline <= 0 = inhibit Timeout
| otherwise = mkGen $ \dt a -> do
res <- stepWire w dt a
case res of
(Right o, w') -> return (Right o, timeout (deadline - dt) w')
(Left e, _) -> return (Left e, inhibit e)
这是 switchBy 的一种变体,它允许您更改一次电线。注意,它传递了一条新线的禁止信号:
switchOn new w0 =
mkGen $ \dt x' ->
let select w' = do
(mx, w) <- stepWire w' dt x'
case mx of
Left ex -> stepWire (new ex) dt x'
Right x -> return (Right x, switchOn new w)
in select w0
这是 (-->) 的变体,它抓住了中断任务链的想法。
infixr 1 ~>
w1 ~> w2 = switchOn ( \e -> case e of
Done -> w2
_ -> inhibit e
) w1