Reflex:创建一个可重置的延迟事件

Reflex: Create a resettable delayed event

我在 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 约束。有没有更地道的方法来写这个函数?

看来我漏掉了比较明显的:

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

可以放宽限制,尽管这会使它们更加冗长。

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