haskus-utils-1.5: Haskus utility modules

Safe HaskellNone
LanguageHaskell2010

Haskus.Utils.Flow

Contents

Description

Control-flow

Synopsis

Documentation

class Monad m => MonadIO (m :: Type -> Type) where #

Monads in which IO computations may be embedded. Any monad built by applying a sequence of monad transformers to the IO monad will be an instance of this class.

Instances should satisfy the following laws, which state that liftIO is a transformer of monads:

Methods

liftIO :: IO a -> m a #

Lift a computation from the IO monad.

Instances
MonadIO IO

Since: base-4.9.0.0

Instance details

Defined in Control.Monad.IO.Class

Methods

liftIO :: IO a -> IO a #

MonadIO Q 
Instance details

Defined in Language.Haskell.TH.Syntax

Methods

liftIO :: IO a -> Q a #

MonadIO m => MonadIO (ListT m) 
Instance details

Defined in ListT

Methods

liftIO :: IO a -> ListT m a #

MonadIO m => MonadIO (IdentityT m) 
Instance details

Defined in Control.Monad.Trans.Identity

Methods

liftIO :: IO a -> IdentityT m a #

(Functor f, MonadIO m) => MonadIO (FreeT f m) 
Instance details

Defined in Control.Monad.Trans.Free

Methods

liftIO :: IO a -> FreeT f m a #

MonadIO m => MonadIO (Excepts es m) 
Instance details

Defined in Haskus.Utils.Variant.Excepts

Methods

liftIO :: IO a -> Excepts es m a #

MonadIO m => MonadIO (StateT s m) 
Instance details

Defined in Control.Monad.Trans.State.Lazy

Methods

liftIO :: IO a -> StateT s m a #

(Error e, MonadIO m) => MonadIO (ErrorT e m) 
Instance details

Defined in Control.Monad.Trans.Error

Methods

liftIO :: IO a -> ErrorT e m a #

class MonadIO m => MonadInIO (m :: Type -> Type) where #

Methods

liftWith :: (forall c. (a -> IO c) -> IO c) -> (a -> m b) -> m b #

Lift with*-like functions into IO (alloca, etc.)

liftWith2 :: (forall c. (a -> b -> IO c) -> IO c) -> (a -> b -> m e) -> m e #

Lift with*-like functions into IO (alloca, etc.)

Instances
MonadInIO IO 
Instance details

Defined in Haskus.Utils.Monad

Methods

liftWith :: (forall c. (a -> IO c) -> IO c) -> (a -> IO b) -> IO b #

liftWith2 :: (forall c. (a -> b -> IO c) -> IO c) -> (a -> b -> IO e) -> IO e #

MonadInIO m => MonadInIO (Excepts es m) 
Instance details

Defined in Haskus.Utils.Variant.Excepts

Methods

liftWith :: (forall c. (a -> IO c) -> IO c) -> (a -> Excepts es m b) -> Excepts es m b #

liftWith2 :: (forall c. (a -> b -> IO c) -> IO c) -> (a -> b -> Excepts es m e) -> Excepts es m e #

MonadInIO m => MonadInIO (StateT s m) 
Instance details

Defined in Haskus.Utils.Monad

Methods

liftWith :: (forall c. (a -> IO c) -> IO c) -> (a -> StateT s m b) -> StateT s m b #

liftWith2 :: (forall c. (a -> b -> IO c) -> IO c) -> (a -> b -> StateT s m e) -> StateT s m e #

Basic operators

(>.>) :: (a -> b) -> (b -> c) -> a -> c infixl 9 Source #

Compose functions

>>> (+1) >.> (*7) <| 1
14

(<.<) :: (b -> c) -> (a -> b) -> a -> c infixr 9 Source #

Compose functions

>>> (+1) <.< (*7) <| 1
8

(|>) :: a -> (a -> b) -> b infixl 0 Source #

Apply a function

>>> 5 |> (*2)
10

(<|) :: (a -> b) -> a -> b infixr 0 Source #

Apply a function

>>> (*2) <| 5
10

(||>) :: Functor f => f a -> (a -> b) -> f b infixl 0 Source #

Apply a function in a Functor

>>> Just 5 ||> (*2)
Just 10

(<||) :: Functor f => (a -> b) -> f a -> f b infixr 0 Source #

Apply a function in a Functor

>>> (*2) <|| Just 5
Just 10

(|||>) :: (Functor f, Functor g) => f (g a) -> (a -> b) -> f (g b) infixl 0 Source #

Apply a function in a Functor

>>> Just [5] |||> (*2)
Just [10]

(<|||) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b) infixr 0 Source #

Apply a function in a Functor

>>> (*2) <||| Just [5]
Just [10]

Monadic/applicative operators

when :: Applicative f => Bool -> f () -> f () #

Conditional execution of Applicative expressions. For example,

when debug (putStrLn "Debugging")

will output the string Debugging if the Boolean value debug is True, and otherwise do nothing.

unless :: Applicative f => Bool -> f () -> f () #

The reverse of when.

whenM :: Monad m => m Bool -> m () -> m () #

Like when, but where the test can be monadic.

unlessM :: Monad m => m Bool -> m () -> m () #

Like unless, but where the test can be monadic.

ifM :: Monad m => m Bool -> m a -> m a -> m a #

Like if, but where the test can be monadic.

guard :: Alternative f => Bool -> f () #

Conditional failure of Alternative computations. Defined by

guard True  = pure ()
guard False = empty

Examples

Expand

Common uses of guard include conditionally signaling an error in an error monad and conditionally rejecting the current choice in an Alternative-based parser.

As an example of signaling an error in the error monad Maybe, consider a safe division function safeDiv x y that returns Nothing when the denominator y is zero and Just (x `div` y) otherwise. For example:

>>> safeDiv 4 0
Nothing
>>> safeDiv 4 2
Just 2

A definition of safeDiv using guards, but not guard:

safeDiv :: Int -> Int -> Maybe Int
safeDiv x y | y /= 0    = Just (x `div` y)
            | otherwise = Nothing

A definition of safeDiv using guard and Monad do-notation:

safeDiv :: Int -> Int -> Maybe Int
safeDiv x y = do
  guard (y /= 0)
  return (x `div` y)

void :: Functor f => f a -> f () #

void value discards or ignores the result of evaluation, such as the return value of an IO action.

Examples

Expand

Replace the contents of a Maybe Int with unit:

>>> void Nothing
Nothing
>>> void (Just 3)
Just ()

Replace the contents of an Either Int Int with unit, resulting in an Either Int '()':

>>> void (Left 8675309)
Left 8675309
>>> void (Right 8675309)
Right ()

Replace every element of a list with unit:

>>> void [1,2,3]
[(),(),()]

Replace the second element of a pair with unit:

>>> void (1,2)
(1,())

Discard the result of an IO action:

>>> mapM print [1,2]
1
2
[(),()]
>>> void $ mapM print [1,2]
1
2

forever :: Applicative f => f a -> f b #

Repeat an action indefinitely.

Examples

Expand

A common use of forever is to process input from network sockets, Handles, and channels (e.g. MVar and Chan).

For example, here is how we might implement an echo server, using forever both to listen for client connections on a network socket and to echo client input on client connection handles:

echoServer :: Socket -> IO ()
echoServer socket = forever $ do
  client <- accept socket
  forkFinally (echo client) (\_ -> hClose client)
  where
    echo :: Handle -> IO ()
    echo client = forever $
      hGetLine client >>= hPutStrLn client

foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b #

The foldM function is analogous to foldl, except that its result is encapsulated in a monad. Note that foldM works from left-to-right over the list arguments. This could be an issue where (>>) and the `folded function' are not commutative.

foldM f a1 [x1, x2, ..., xm]

==

do
  a2 <- f a1 x1
  a3 <- f a2 x2
  ...
  f am xm

If right-to-left evaluation is required, the input list should be reversed.

Note: foldM is the same as foldlM

foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () #

Like foldM, but discards the result.

forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) #

forM is mapM with its arguments flipped. For a version that ignores the results see forM_.

forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m () #

forM_ is mapM_ with its arguments flipped. For a version that doesn't ignore the results see forM.

As of base 4.8.0.0, forM_ is just for_, specialized to Monad.

forMaybeM :: Monad m => [a] -> (a -> m (Maybe b)) -> m [b] Source #

Composition of catMaybes and forM

>>> let f x = if x > 3 then putStrLn "OK" >> return (Just x) else return Nothing
>>> forMaybeM [0..5] f
OK
OK
[4,5]

mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) #

Map each element of a structure to a monadic action, evaluate these actions from left to right, and collect the results. For a version that ignores the results see mapM_.

mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m () #

Map each element of a structure to a monadic action, evaluate these actions from left to right, and ignore the results. For a version that doesn't ignore the results see mapM.

As of base 4.8.0.0, mapM_ is just traverse_, specialized to Monad.

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) #

Evaluate each monadic action in the structure from left to right, and collect the results. For a version that ignores the results see sequence_.

replicateM :: Applicative m => Int -> m a -> m [a] #

replicateM n act performs the action n times, gathering the results.

replicateM_ :: Applicative m => Int -> m a -> m () #

Like replicateM, but discards the result.

filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] #

This generalizes the list-based filter function.

join :: Monad m => m (m a) -> m a #

The join function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level.

Examples

Expand

A common use of join is to run an IO computation returned from an STM transaction, since STM transactions can't perform IO directly. Recall that

atomically :: STM a -> IO a

is used to run STM transactions atomically. So, by specializing the types of atomically and join to

atomically :: STM (IO b) -> IO (IO b)
join       :: IO (IO b)  -> IO b

we can compose them as

join . atomically :: STM (IO b) -> IO b

to run an STM transaction and the IO action it returns.

(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 #

Right-to-left composition of Kleisli arrows. (>=>), with the arguments flipped.

Note how this operator resembles function composition (.):

(.)   ::            (b ->   c) -> (a ->   b) -> a ->   c
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 #

Left-to-right composition of Kleisli arrows.

loopM :: Monad m => (a -> m (Either a b)) -> a -> m b #

A monadic version of loop, where the predicate returns Left as a seed for the next loop or Right to abort the loop.

whileM :: Monad m => m Bool -> m () #

Keep running an operation until it becomes False. As an example:

whileM $ do sleep 0.1; notM $ doesFileExist "foo.txt"
readFile "foo.txt"

If you need some state persisted between each test, use loopM.

intersperseM_ :: Monad m => m () -> [a] -> (a -> m ()) -> m () Source #

forM_ with interspersed action

>>> intersperseM_ (putStr ", ") ["1","2","3","4"] putStr
1, 2, 3, 4

forLoopM_ :: Monad m => a -> (a -> Bool) -> (a -> a) -> (a -> m ()) -> m () Source #

Fast for-loop in a Monad (more efficient than forM_ [0..n] for instance).

>>> forLoopM_ (0::Word) (<5) (+1) print
0
1
2
3
4

forLoop :: a -> (a -> Bool) -> (a -> a) -> acc -> (acc -> a -> acc) -> acc Source #

Fast fort-loop with an accumulated result

>>> let f acc n = acc ++ (if n == 0 then "" else ", ") ++ show n
>>> forLoop (0::Word) (<5) (+1) "" f
"0, 1, 2, 3, 4"

Variant based operators

Monad transformers

lift :: (MonadTrans t, Monad m) => m a -> t m a #

Lift a computation from the argument monad to the constructed monad.