在反应香蕉中,我有一个事件流,它产生一系列数字,其中一些连续重复多次(我不关心所有重复,只是顺序重复)。如何修改该事件流以仅包含非顺序重复项?
我尝试使用更改将其转换为一种行为,认为该行为只会在事件是新数字时“更改”,而是每次收到新的输入事件时行为都会触发更改事件。
在反应香蕉中,我有一个事件流,它产生一系列数字,其中一些连续重复多次(我不关心所有重复,只是顺序重复)。如何修改该事件流以仅包含非顺序重复项?
我尝试使用更改将其转换为一种行为,认为该行为只会在事件是新数字时“更改”,而是每次收到新的输入事件时行为都会触发更改事件。
请注意,该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
; 它只是让您观察a Behavior
in的变化NetworkDescription
,以便您可以将其粘合到外部框架。的行为changes
被描述为changes (stepper x e)
≡ return (calm e)
,因此往返事件通过stepper
并且除了(它只是丢弃除第一个之外的所有同时发生的事件)changes
之外没有任何影响。calm
有一个组合器来丢弃不改变值的事件是很有用的,我认为其他一些 FRP 框架内置了一个。但是你可以很容易地编写自己的,正如 Heinrich 的回答所示。