HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Moduletimeout-0.1.1Haskell2010

Control.Timeout

This module provides generalized sleep and timeout functions.

Example:

module Main where

import Control.Timeout (timeout, sleep)
main :: IO ()
main = do
    timeout 1 $ sleep 2  -- Will return IO Nothing
    timeout 2 $ sleep 1  -- Will return IO (Just ())
    return ()
  • 2 types
  • 2 values
  • Packagetimeout-0.1.1
  • Exports4
  • LanguageHaskell2010
  • LicenceMIT
  • SourceTimeout.hs
newtypenewtype NominalDiffTime
#

This is a length of time, as measured by UTC. It has a precision of 10^-12 s.

Conversion functions such as fromInteger and realToFrac will treat it as seconds. For example, (0.010 :: NominalDiffTime) corresponds to 10 milliseconds.

It has a precision of one picosecond (= 10^-12 s). Enumeration functions will treat it as picoseconds.

It ignores leap-seconds, so it's not necessarily a fixed amount of clock time. For instance, 23:00 UTC + 2 hours of NominalDiffTime = 01:00 UTC (+ 1 day), regardless of whether a leap-second intervened.

Instances13Enum, Eq, Fractional, Data, Num, Ord, …
newtypenewtype Timeout
#

Exception used for timeout handling

Constructors

Instances3Eq, Show, Exception
valuetimeout :: (MonadMask m, MonadIO m) => NominalDiffTime -> m a -> m (Maybe a)
#

Wrap an MonadIO computation to time out and return Nothing in case no result is available within n seconds. In case a result is available before the timeout expires, Just a is returned. A negative timeout interval means "timeout immediately".

The design of this combinator was guided by the objective that timeout n f should behave exactly the same as f as long as f doesn't time out. This means that f has the same myThreadId it would have without the timeout wrapper. Any exceptions f might throw cancel the timeout and propagate further up. It also possible for f to receive exceptions thrown to it by another thread.

A tricky implementation detail is the question of how to abort an IO computation. This combinator relies on asynchronous exceptions internally. The technique works very well for computations executing inside of the Haskell runtime system, but it doesn't work at all for non-Haskell code. Foreign function calls, for example, cannot be timed out with this combinator simply because an arbitrary C function cannot receive asynchronous exceptions. When timeout is used to wrap an FFI call that blocks, no timeout event can be delivered until the FFI call returns, which pretty much negates the purpose of the combinator. In practice, however, this limitation is less severe than it may sound. Standard I/O functions like System.IO.hGetBuf, System.IO.hPutBuf, Network.Socket.accept, or System.IO.hWaitForInput appear to be blocking, but they really don't because the runtime system uses scheduling mechanisms like select(2) to perform asynchronous I/O, so it is possible to interrupt standard socket I/O or file I/O using this combinator.