注意してください
mapAccum :: acc -> Event t (acc -> (x, acc)) -> (Event t x, Behavior t acc)
そのため、蓄積する初期値:: acc
と、出力値を生成しながらその蓄積値を更新する関数を生成するイベントが必要です::x
。(通常、このようなイベントは、 を介して一部の関数を部分的に適用することで作成し<$>
ます。) その結果、値がx
現れるたびに値を起動する新しいイベントと、現在の累積値を含む動作が得られます。
mapAccum
イベントがあり、関連する動作とイベントを作成する場合に使用します。
たとえば、他の質問のeTime :: Event t Int
問題ドメインで、不規則に発生するイベントがeDeltaTime :: Event t Int
あり、差とbTimeAgain :: Behaviour t Int
現在使用されている時間を計算したいとします。
type Time = Int
type DeltaTime = Time
getDelta :: Time -> Time -> (DeltaTime,Time)
getDelta new old = (new-old,new)
getDelta new = \old -> (new-old,new)
次のステップを明確にするために、次のように書くこともできました。
deltaMaker :: Event t (Time -> (DeltaTime,Time))
deltaMaker = getDelta <$> eTime
(eDeltaT,bTimeAgain) = mapAccum 0 $ deltaMaker
この場合、bTimeAgain
は のイベントと同じ値を持つ動作になりますeTime
。これは、getDelta
関数が変更されずに値からそのまま通過するためnew
に発生します。(単独で使用したい場合は、 を使用していたでしょう。) が必要ない場合は、 と書くだけで済みます。eTime
acc
bTimeAgain
stepper :: a -> Event t a -> Behaviour t a
bTimeAgain
(eDeltaT,_) = mapAccum 0 $ deltaMaker