Haskell中的计时器(Control.Concurrent.Timer):重复执行

时间:2019-08-22 10:57:37

标签: haskell timer

试图找出最佳实践,以使用Control.Concurrent.Timer处理Haskell中的重复操作。找不到好的例子。

假设我重复了必须在应用程序中执行的操作。假设它是从某些网页上获取数据。

import Control.Concurrent.Suspend.Lifted 
import Control.Concurrent.Timer

main :: IO ()
main = do
  url <- fetchUrl :: IO Url
  doSomethingWithUrl url

,我希望在main内部重复获取url,因此数据始终是新鲜的。怎么做?

1 个答案:

答案 0 :(得分:1)

您的需求听起来像它们适合IORef或MVar。键入但未经测试的代码是:

import Data.IORef (readIORef, writeIORef, newIORef)
import Control.Concurrent (threadDelay,forkIO)
import Control.Monad (void)

main :: IO ()
main = do
  ref <- newIORef mempty {- or default value -}
  _ <- forkIO (updatePeriodically fetchUrl ref)
  scotty $ do
        liftIO (readIORef ref) >>= etcEtc

updatePeriodically :: (IO SomeType) -> IORef SomeType -> IO ()
updatePeriodically op ref =
    let update = op >>= writeIORef ref
    forever $ threadDelay periodInMicroSeconds >> void (forkIO update)

这不是完美的,如果fetchUrl调用中的一个严重延迟,则其写操作可能会阻塞很快返回的较新的调用。这可能是个小问题,但您可以使用计数器来处理它,然后进行比较和交换操作。