4

假设我有

x :: Event t (A,B)

我可以得到它的第一个组件:

fst <$> x :: Event t A

但是,即使第一个组件没有更改,此事件也会触发。我想避免这种情况,因为它会引发昂贵的重新计算。

A是 的一个实例Eq,因此我希望能够删除第一个组件与其最后一个值相比未更改的连续事件。

理想情况下,我想要一个功能

filterDups :: Eq a => Event t a -> Event t a

这将在不诉诸Moment单子的情况下做到这一点。可能吗?或者最好的方法是什么?

4

3 回答 3

2

我从来没有使用过反应香蕉,也没有测试过,所以要小心。尽管如此,这是一个至少可以进行类型检查的想法。我们将accumE用来记住一些关于过去事件的事情。

notice x (old, new) = (new, Just x)

changed (Just old, Just new) = guard (old /= new) >> return new
changed (_, new) = new

justChanges :: Eq a => Event t a -> Event t a
justChanges e = filterJust $ changed <$> accumE (Nothing, Nothing) (notice <$> e)
于 2013-10-11T15:31:15.393 回答
2

stepper该解决方案使用(或滥用)函数更新Behavior“稍晚于”的事实Event请参阅文档中的评论

首先创建一个Behavior基于Event,你必须在你的解决方案中找到一个合适的第一个值Behavior,为简单起见,我假设你的对的第一个元素是一个Int

x :: Event t (Int, b)

firstB :: Behavior t Int
firstB = stepper 0 $ fst <$> x

然后您可以使用该filterApply功能:

filterDups e = filterApply (firstNotEq <$> firstB) e
    where firstNotEq old (new, _) = new /= old
          firstB                  = stepper 0 $ fst <$> e

看一下这个要点,了解一个使用Threepenny GUI的简单示例。

于 2013-10-12T01:53:10.757 回答
2

You have to remember information about the history of the event to do what you want. As other answers have already mentioned, you can use accumE for that purpose. Here a succinct definition:

unique :: Eq a => Event t a -> Event t a
unique = filterJust . accumE Nothing
       . fmap (\a acc -> if Just a == acc then Nothing else Just a)
于 2013-10-12T10:36:20.330 回答