リアクティブバナナには、一連の番号を生成するイベントストリームがあり、そのうちのいくつかは連続して数回繰り返されます(すべての重複ではなく、連続した重複だけです)。連続していない重複のみを含むようにそのイベントストリームを変更するにはどうすればよいですか?
変更を使用して、イベントが新しい番号の場合にのみ動作が「変更」されると考えて動作に変換しようとしましたが、代わりに、新しい入力イベントが受信されるたびに動作が変更イベントをトリガーします。
リアクティブバナナには、一連の番号を生成するイベントストリームがあり、そのうちのいくつかは連続して数回繰り返されます(すべての重複ではなく、連続した重複だけです)。連続していない重複のみを含むようにそのイベントストリームを変更するにはどうすればよいですか?
変更を使用して、イベントが新しい番号の場合にのみ動作が「変更」されると考えて動作に変換しようとしましたが、代わりに、新しい入力イベントが受信されるたびに動作が変更イベントをトリガーします。
このchanges
関数は、GUIツールキットなどへのバインドにのみ使用する必要があり、イベントや動作を使用した通常のプログラミングには使用しないでください。
mapAccum
重複イベントの発生を抑制する関数は、およびfilterJust
コンビネータで次のように表すことができます。
skipEqual :: Eq a => Event t a -> Event t a
skipEqual = filterJust . fst . mapAccum Nothing . fmap f
where
f y (Just x) = if x == y then (Nothing,Just x) else (Just y,Just y)
f y Nothing = (Just y, Just y)
test = interpretModel skipEqual $ map (:[]) [1 :: Int,1,2,3,3,2]
実行test
すると
*Main> test
[[1],[],[2],[3],[],[2]]
望んだ通りに。
言い換えれば、あなたは単に Event
出来事のリストとして想像し、そしてあなたの最愛の「リスト」コンビネータをそれに適用することができます。
まあ、changes
何もに変えませんBehavior
; の変化を観察できるので、外部フレームワークに接着できます。の動作は≡として記述されているため、イベントをラウンドトリップすると、 (最初の発生を除くすべての同時発生を単に破棄する)以外の効果はありません。Behavior
NetworkDescription
changes
changes (stepper x e)
return (calm e)
stepper
changes
calm
値を変更しないオカレンスを破棄するコンビネータがあると便利です。他のFRPフレームワークにはコンビネータが組み込まれていると思います。しかし、ハインリッヒの答えが示すように、独自のコンビネータを簡単に作成できます。