【发布时间】:2012-04-17 06:58:51
【问题描述】:
在响应式香蕉中,我有一个事件流,它产生一系列数字,其中一些连续重复多次(我不关心所有重复,只是顺序重复)。如何修改该事件流以仅包含非顺序重复项?
我尝试使用更改将其转换为一种行为,认为该行为只会在事件为新数字时“更改”,但每次收到新输入事件时该行为都会触发更改事件。
【问题讨论】:
标签: haskell reactive-programming frp reactive-banana
在响应式香蕉中,我有一个事件流,它产生一系列数字,其中一些连续重复多次(我不关心所有重复,只是顺序重复)。如何修改该事件流以仅包含非顺序重复项?
我尝试使用更改将其转换为一种行为,认为该行为只会在事件为新数字时“更改”,但每次收到新输入事件时该行为都会触发更改事件。
【问题讨论】:
标签: haskell reactive-programming frp reactive-banana
请注意,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 想象成一个出现的列表,然后将您心爱的“列表”组合器应用于该列表。
【讨论】:
apply 对事件进行行为。 <@> 和 <@ 运算符用于此目的。此外,您可以在行为和事件之间使用相互递归。
好吧,changes 不会把任何东西变成Behavior;它只是让您观察 Behavior 在NetworkDescription 中的变化,以便您可以将其粘合到外部框架。 behaviour of changes 被描述为changes (stepper x e) ≡ return (calm e),因此通过stepper 和changes 来回传递一个事件除了calm 之外没有任何影响(它只是丢弃所有同时发生的事件,但第一个事件除外)。
拥有一个组合器来丢弃不改变值的事件很有用,我认为其他一些 FRP 框架内置了一个。但是正如 Heinrich 的回答所示,您可以很容易地编写自己的框架。
【讨论】: