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
可以放宽限制,尽管这会使它们更加冗长。
不过,最后我采用了我的第一个解决方案。我认为性能影响很小,它简化了程序的其他一些方面。
我在 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
可以放宽限制,尽管这会使它们更加冗长。
不过,最后我采用了我的第一个解决方案。我认为性能影响很小,它简化了程序的其他一些方面。