在反应香蕉中,我有一个产生一系列数字的事件流,其中一些数字连续重复几次(我不关心所有重复数据,只关注顺序重复数据)。如何修改该事件流以仅包含非连续重复项?
我尝试使用更改将其转换为行为,认为行为只会在事件为新数字时“更改”,而是每次收到新的输入事件时行为都会触发更改事件。
答案 0 :(得分:6)
请注意,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
想象为事件列表,然后将您心爱的“列表”组合器应用于此。
答案 1 :(得分:0)
好吧,changes
不会将任何内容变成Behavior
;它只是让你观察1}} Behavior
中NetworkDescription
的变化,这样你就可以将它粘贴到外部框架上。 behaviour of changes
被描述为changes (stepper x e)
≡return (calm e)
,因此通过stepper
和changes
对事件进行往返除calm
之外不会产生任何影响(它只是丢弃所有同时发生但第一次发生)。
使用组合器来丢弃不会改变值的事件是有用的,我认为其他一些FRP框架内置了一个。但是你可以很容易地编写自己的,就像Heinrich的答案所示。