9

AFRP、Yampa、Reactive-bananaなどのほとんどのHaskell FRPフレームワークは、連続的な時変関数と個別の関数を区別します。通常、彼らはそれらを行動やイベントと呼びます。

1つの例外は、イベントをモデル化するために抑制モノイドを使用するNetwireです。そのようなアプローチの長所と短所は何ですか?

特に、ロボット制御へのFRPの応用に興味があります。たとえば、このペーパーhttp://haskell.cs.yale.edu/?post_type=publication&p=182は、イベントを使用してFRPでタスクとHSM抽象化をエンコードする方法を示しています。これを直接Netwireに変換できますか?

4

2 に答える 2

10

潜在的に抑制された信号としてのイベントの利点は、最も複雑な反応式を非常に簡潔にエンコードできることです。押すと「はい」、それ以外の場合は「いいえ」と表示されるスイッチを想像してみてください。

"yes" . switchPressed <|> "no"

アイデアはswitchPressed、対応するイベントが発生した場合はIDワイヤーのように機能し、それ以外の場合は抑制します。そこで<|>、最初のワイヤーが抑制された場合、2番目のワイヤーが試行されます。これは、2つのボタン(左と右)によって制御される架空のロボットアームです。

robotArm = integral_ 0 . direction
direction =
    ((-1) . leftPressed  <|> 0) +
    (1    . rightPressed <|> 0)

ロボットアームは架空のものですが、このコードは架空のものではありません。これは、Netwireでこれを書く方法です。

于 2013-02-01T22:10:12.130 に答える
1

いくつかの試行の後、必要な動作を実装しました。基本的に、必要なイベントの概念をキャッチするカスタム阻害剤タイプを作成します。私の場合は

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
于 2013-02-06T05:37:43.740 に答える