Ste*_*gan 5 haskell frp reflex
我在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
Run Code Online (Sandbox Code Playgroud)
但是使用widgetHold似乎有些矫kill过正。似乎我们只应该真正需要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
Run Code Online (Sandbox Code Playgroud)
限制可以放宽,但这会使它们更加冗长。
但最终我还是选择了第一个解决方案。我认为对性能的影响很小,并且它简化了程序的其他一些方面。