    {-# LANGUAGE ScopedTypeVariables #-}

    -- |
    -- This package provides the choice operator ('||>') for
    -- IO monad.

    module Control.Exception.IOChoice where

    import Control.Exception (IOException)
    import qualified Control.Exception as E

    -- |
    -- If 'IOException' occurs or 'goNext' is used in the left IO,
    -- then the right IO is performed. Note that 'fail'
    -- throws 'IOException'.

    (||>) :: IO a -> IO a -> IO a
    x ||> y = x `E.catch` (\(_ :: IOException) -> y)

    infixr 3 ||>

    -- | Go to the next 'IO' monad by throwing 'IOException'.
    goNext :: IO a
    goNext = E.throwIO $ userError "goNext for IO"

    -- | Run any one 'IO' monad.
    runAnyOne :: [IO a] -> IO a
    runAnyOne = foldr (||>) goNext