Skip to content

Instantly share code, notes, and snippets.

@homam
Created July 25, 2015 13:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save homam/11c19f27454ee0ba1b56 to your computer and use it in GitHub Desktop.
Save homam/11c19f27454ee0ba1b56 to your computer and use it in GitHub Desktop.
Timer, setInterval in Haskell
import Control.Concurrent
import Control.Exception
setInterval :: Int -> a -> (a -> IO a) -> IO ()
setInterval microsecs a action = do
mvar <- newEmptyMVar
_ <- setInterval' microsecs a mvar action
takeMVar mvar
setInterval' :: Int -> a -> MVar () -> (a -> IO a) -> IO ThreadId
setInterval' microsecs a mvar action =
forkIO (loop a `finally` putMVar mvar ())
where
loop i = do
threadDelay microsecs
j <- action i
loop j
main :: IO ()
main = setInterval 1000000 (1, 1)
(\ (x, y) -> do
print $ "fib " ++ show x
return (y, x + y)
)
import Control.Monad.State
import Control.Concurrent
import Control.Exception
setInterval :: Int -> a -> StateT a IO () -> IO ()
setInterval microsecs a action = do
mvar <- newEmptyMVar
_ <- evalStateT (setInterval' microsecs mvar action) a
takeMVar mvar
setInterval' :: Int -> MVar () -> StateT a IO () -> StateT a IO ThreadId
setInterval' microsecs mvar action = do
i <- get
lift $ forkIO (evalStateT loop i `finally` putMVar mvar ())
where
loop = do
action
lift $ threadDelay microsecs
loop
main :: IO ()
main = setInterval 1000000 (1, 1)
(do
(x, y) <- get
lift $ print $ "fib " ++ show x
put (y, x + y)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment