FRP の感触をつかもうとして netwire パッケージをいじっていますが、簡単な質問があります。
次の単純なワイヤーから始めて、5 秒ごとに (約) イベントを発行できます。
myWire :: (Monad m, HasTime t s) => Wire s () m a Float
myWire = timeF
myWire' :: (Monad m, HasTime t s) => Wire s () m a Int
myWire' = fmap round myWire
myEvent :: (Monad m, HasTime t s) => Wire s () m a (Event Int)
myEvent = periodic 5 . myWire'
これは非常に素晴らしく簡単ですが、次にやりたいことは、生成された各イベントをワイヤーにマップして、更新を監視できるようにすることです。次のようなアキュムレータ関数があります。
eventList :: (Monad m, HasTime t s)
=> Wire s () m a (Event [Wire s () m a Int])
eventList = accumE go [] . myEvent
where go soFar x = f x : soFar
f x = for 10 . pure x --> pure 0
次に、イベントのトリガーが開始されるまで禁止する新しいワイヤを導入しeventList
ます。次のようにします。
myList :: (Monad m, HasTime t s) => Wire s () m a [Wire s () m a Int]
myList = asSoonAs . eventList
だから私はイベントからワイヤのリストを含むワイヤに行きました。最後に、これらの各ワイヤをステップ実行して結果のリストを生成するワイヤを導入します。
myNums :: (Monad m, HasTime t s) => Wire s () m [Wire s () m a Int] [Int]
myNums = mkGen $ \dt wires -> do
stepped <- mapM (\w -> stepWire w dt $ Right undefined) wires
let alive = [ (r, w) | (Right r, w) <- stepped ]
return (Right (map fst alive), myNums)
myNumList :: (Monad m, HasTime t s) => Wire s () m a [Int]
myNumList = myNums . myList
最後に、すべてをテストするためのメイン ルーチンがあります。
main = testWire clockSession_ myNumList
私が期待しているのは、リスト内の各要素が 10 秒間の作成時間を示し、その後、要素がゼロを表示する、成長するリストです。私が代わりに得ているのは、静的値のリストの増加です。たとえば、いくつかの手順を実行すると、次のようになります。
[0]
[5, 0]
[10, 5, 0]
[15, 10, 0, 0]
等々。私が実際に見ているのは、
[0]
[5, 0]
[10, 5, 0]
[15, 10, 5, 0]
したがって、アキュムレータ関数が機能していることはわかっています。作成されたすべてのイベントがワイヤに変換されています。しかし、私が見ていないのは、これらのワイヤが時間の経過とともに異なる値を放出していることです。私のステートメントfor 10 . pure x --> pure 0
は、時間が経過した後、それらを 0 を発行するように切り替える必要があります。
私はまだFRPに慣れていないので、何か重要なことを根本的に誤解している可能性があります(おそらくそうです).