16

I'm brand new to Haskell and I'm trying to figure out how to schedule a callback to be fired X seconds from now (and no sooner).

In searching Hoogle and Google, I've discovered:

http://www.haskell.org/ghc/docs/latest/html/libraries/base/GHC-Event.html

as well as:

http://hackage.haskell.org/packages/archive/base/4.3.1.0/doc/html/System-Event.html

Both of these feature a "registerTimeout" function that seems to do what I want. However, System.Event appears to no longer be in the latest builds of Haskell and GHC.Event is marked as being internal.

Is there some user-space substitute I could use? I'd prefer not to use the timing functions intended for GLUT (unless that's the prescribed way of achieving my goal), and System.Timeout doesn't appear to quite what I want; it is intended to put a maximum on the amount of time something can take rather than a minimum.

Thank you for your input!

zslayton
  • 51,416
  • 9
  • 35
  • 50

1 Answers1

19

I would simply execute the callback on its own thread after a delay. This is a GHC-ism.

import Control.Concurrent (forkIO, threadDelay)

-- | Run the callback after the given number of milliseconds.
runAfterDelay :: Int -> IO () -> IO ()
runAfterDelay t f = forkIO (threadDelay t >> f)

Threads in GHC are exceptionally light-weight, so this won't take tie up system resources.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • 1
    That makes sense! Thanks very much. I had been avoiding threads because I perceived them as being expensive to spawn/join. I'm curious to see how many of these I can have sitting in a process at once without memory consumption becoming a huge issue. Time to start benchmarking. – zslayton Mar 27 '13 at 23:55
  • 3
    @Zack: Don't worry about the overhead, it's very small. See: http://stackoverflow.com/questions/5847642/haskell-lightweight-threads-overhead-and-use-on-multicores – Dietrich Epp Mar 28 '13 at 00:31
  • Whoa, so it is. I'm really starting to like this Haskell business. – zslayton Mar 28 '13 at 14:23