いくつかの試行の後、必要な動作を実装しました。基本的に、必要なイベントの概念をキャッチするカスタム阻害剤タイプを作成します。私の場合は
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の変形であり、ワイヤを1回変更できます。新しいワイヤの抑制信号を渡すことに注意してください。
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