2012-04-03 87 views
7

在反應香蕉中,我有一個事件流產生一系列數字,其中一些數字連續重複數次(我不關心所有重複,只是順序重複)。我如何修改該事件流以僅包含非順序重複項?你如何刪除反應香蕉中的重複事件

我嘗試使用更改將其轉換爲一種行爲,認爲行爲只會在事件是新數字時「更改」,而行爲每次收到新輸入事件時都會觸發更改事件。

回答

6

注意,changes函數應該只用於結合GUI工具包和thelike,應該用於事件和行爲的常規節目。

該supresses重複的事件發生的函數可以在mapAccumfilterJust組合子來表示如下

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作爲出現的列表,然後將你心愛的「列表」組合子應用到那個。

+0

哦,爲什麼我沒有想到這個?!我已經從我的答案中刪除了醜陋的實現來支持這個。 – ehird 2012-04-03 17:41:06

+1

如果你不應該使用改變,你如何做一些有意義的行爲? – Orclev 2012-04-04 00:26:11

+0

@Orclev:您可以將事件應用於行爲。 '<@>'和'<@'運算符用於此。此外,您可以在行爲和事件之間使用相互遞歸。 – 2012-04-04 07:36:37

0

那麼,changes不會把任何東西變成Behavior;它只是讓你觀察BehaviorNetworkDescription的變化,以便你可以粘貼到外部框架。 behaviour of changes被描述爲changes (stepper x e)≡,所以通過stepperchanges往返跳過一個事件除calm(其只簡單地丟棄除第一個以外的所有同時發生)之外將沒有任何效果。

讓組合者放棄不會改變值的事件是很有用的,我認爲其他一些FRP框架內置了一個框架。但正如海因裏希的答案所示,您可以很容易地編寫自己的框架。