2012-04-03 15 views
7

リアクティブバナナでは、一連の番号を生成するイベントストリームがありますが、そのうちのいくつかは連続して何回か繰り返されます(私はすべての重複、ちょうど連続した複製)。非連続の重複のみを含むようにイベントストリームを変更するにはどうすればよいですか?リアクティブバナナで繰り返されるイベントを削除するには

変更を使用して、イベントが新しい番号だったときに動作が「変更される」と思う動作に変換しようとしましたが、代わりに新しい入力イベントが受信されるたびに変更イベントがトリガーされます。

答えて

6

注意、それがはイベントや行動との定期的なプログラミングのために使用すべきではありません。所望に応じて

test実行

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] 

を次のように重複したイベントの発生をsupresses関数mapAccumfilterJustコンビネータで表現することができる

*Main> test 
[[1],[],[2],[3],[],[2]] 

を与えます。

つまり、出現のリストとしてEventを想像して、あなたの最愛の "リスト"コンビネータをそれに適用することができます。

+0

ああ、なぜ私はそれを考えなかったのですか?私はこれに賛成する私の答えから醜い実装を削除しました。 – ehird

+1

変更を使用すべきでない場合は、ビヘイビアで意味のあることはどうしたらよいですか? – Orclev

+0

@Orclev:イベントに動作を適用することができます。 '<@>'と '<@'演算子がそのために使われます。また、ビヘイビアとイベントの相互再帰を使用することもできます。 –

0

まあ、changesは何もBehaviorに変えません。 に変更し、Behaviorの変更をNetworkDescriptionにして、それを外部フレームワークに接着することができます。 behaviour of changeschanges (stepper x e)return (calm e)と記述されているので、イベントをstepperchangesでラウンドトリップすると、calm以外の効果はありません(これは、すべての同時の出現を単純に破棄します)。

値を変更しないオカレンスを破棄するためのコンビネータを使用すると便利です。他のFRPフレームワークも組み込まれていると思いますが、ハインリッヒの回答が示すように、簡単に書くことができます。 changes機能はが唯一のGUIツールキットとthelikeに結合するために使用される必要があることを

関連する問題