5

我在 Haskell 中使用 Reflex,并试图创建一个事件,该事件会在一段时间后触发(出于提问目的),比如说 2 秒。但是,每当原始事件触发时,计数器都应该重置,因此如果原始事件在 1 秒内触发两次,则第二个事件应该只有一次触发:在最后一个原始事件之后 2 秒。

我已经设法用

delayedReset :: MonadWidget t m => Event t () -> m (Event t ())
delayedReset ev = fmap (switch . current) . widgetHold (return never) $ timer <$ ev
  where
    timer = delay 2 =<< getPostBuild

但是使用 widgetHold 似乎有点过分;看来我们应该只需要一个 MonadHold 约束。有没有更惯用的方法来编写这个函数?

4

1 回答 1

1

似乎我错过了相当明显的:

delayedReset :: MonadWidget t m => Event t () -> m (Event t ())
delayedReset ev = do
    endEv <- delay 2 ev
    countDyn <- foldDyn ($) (0 :: Int) $ leftmost
      [ (+1) <$ ev, subtract 1 <$ endEv ]
    return $ attachPromptlyDynWithMaybe ifZero countDyn endEv
  where
    ifZero 0 a = Just a
    ifZero _ _ = Nothing

可以放宽约束,但这会使它们更加冗长。

不过,最后我还是选择了我的第一个解决方案。我认为对性能的影响很小,它简化了程序的其他一些方面。

于 2018-01-23T11:52:10.797 回答