free-4.12.4: Monads for free

Copyright(C) 2013 Edward Kmett
LicenseBSD-style (see the file LICENSE)
MaintainerEdward Kmett <ekmett@gmail.com>
Stabilityprovisional
PortabilityMPTCs, fundeps
Safe HaskellSafe
LanguageHaskell2010

Control.Monad.Trans.Iter

Contents

Description

Based on Capretta's Iterative Monad Transformer

Unlike Free, this is a true monad transformer.

Synopsis

Documentation

Functions in Haskell are meant to be pure. For example, if an expression has type Int, there should exist a value of the type such that the expression can be replaced by that value in any context without changing the meaning of the program.

Some computations may perform side effects (unsafePerformIO), throw an exception (using error); or not terminate (let infinity = 1 + infinity in infinity).

While the IO monad encapsulates side-effects, and the Either monad encapsulates errors, the Iter monad encapsulates non-termination. The IterT transformer generalizes non-termination to any monadic computation.

Computations in IterT (or Iter) can be composed in two ways:

  • Sequential: Using the Monad instance, the result of a computation can be fed into the next.
  • Parallel: Using the MonadPlus instance, several computations can be executed concurrently, and the first to finish will prevail. See also the cabbage example.

The iterative monad transformer

newtype IterT m a #

The monad supporting iteration based over a base monad m.

IterT ~ FreeT Identity

Constructors

IterT 

Fields

Instances

MonadTrans IterT # 

Methods

lift :: Monad m => m a -> IterT m a #

MonadError e m => MonadError e (IterT m) # 

Methods

throwError :: e -> IterT m a #

catchError :: IterT m a -> (e -> IterT m a) -> IterT m a #

MonadReader e m => MonadReader e (IterT m) # 

Methods

ask :: IterT m e #

local :: (e -> e) -> IterT m a -> IterT m a #

reader :: (e -> a) -> IterT m a #

MonadState s m => MonadState s (IterT m) # 

Methods

get :: IterT m s #

put :: s -> IterT m () #

state :: (s -> (a, s)) -> IterT m a #

MonadWriter w m => MonadWriter w (IterT m) # 

Methods

writer :: (a, w) -> IterT m a #

tell :: w -> IterT m () #

listen :: IterT m a -> IterT m (a, w) #

pass :: IterT m (a, w -> w) -> IterT m a #

Monad m => MonadFree Identity (IterT m) # 

Methods

wrap :: Identity (IterT m a) -> IterT m a #

Monad m => Monad (IterT m) # 

Methods

(>>=) :: IterT m a -> (a -> IterT m b) -> IterT m b #

(>>) :: IterT m a -> IterT m b -> IterT m b #

return :: a -> IterT m a #

fail :: String -> IterT m a #

Monad m => Functor (IterT m) # 

Methods

fmap :: (a -> b) -> IterT m a -> IterT m b #

(<$) :: a -> IterT m b -> IterT m a #

MonadFix m => MonadFix (IterT m) # 

Methods

mfix :: (a -> IterT m a) -> IterT m a #

Monad m => Applicative (IterT m) # 

Methods

pure :: a -> IterT m a #

(<*>) :: IterT m (a -> b) -> IterT m a -> IterT m b #

(*>) :: IterT m a -> IterT m b -> IterT m b #

(<*) :: IterT m a -> IterT m b -> IterT m a #

Foldable m => Foldable (IterT m) # 

Methods

fold :: Monoid m => IterT m m -> m #

foldMap :: Monoid m => (a -> m) -> IterT m a -> m #

foldr :: (a -> b -> b) -> b -> IterT m a -> b #

foldr' :: (a -> b -> b) -> b -> IterT m a -> b #

foldl :: (b -> a -> b) -> b -> IterT m a -> b #

foldl' :: (b -> a -> b) -> b -> IterT m a -> b #

foldr1 :: (a -> a -> a) -> IterT m a -> a #

foldl1 :: (a -> a -> a) -> IterT m a -> a #

toList :: IterT m a -> [a] #

null :: IterT m a -> Bool #

length :: IterT m a -> Int #

elem :: Eq a => a -> IterT m a -> Bool #

maximum :: Ord a => IterT m a -> a #

minimum :: Ord a => IterT m a -> a #

sum :: Num a => IterT m a -> a #

product :: Num a => IterT m a -> a #

(Monad m, Traversable m) => Traversable (IterT m) # 

Methods

traverse :: Applicative f => (a -> f b) -> IterT m a -> f (IterT m b) #

sequenceA :: Applicative f => IterT m (f a) -> f (IterT m a) #

mapM :: Monad m => (a -> m b) -> IterT m a -> m (IterT m b) #

sequence :: Monad m => IterT m (m a) -> m (IterT m a) #

MonadIO m => MonadIO (IterT m) # 

Methods

liftIO :: IO a -> IterT m a #

Monad m => Alternative (IterT m) # 

Methods

empty :: IterT m a #

(<|>) :: IterT m a -> IterT m a -> IterT m a #

some :: IterT m a -> IterT m [a] #

many :: IterT m a -> IterT m [a] #

Monad m => MonadPlus (IterT m) #

Capretta's race combinator. Satisfies left catch.

Methods

mzero :: IterT m a #

mplus :: IterT m a -> IterT m a -> IterT m a #

MonadThrow m => MonadThrow (IterT m) # 

Methods

throwM :: Exception e => e -> IterT m a #

MonadCatch m => MonadCatch (IterT m) # 

Methods

catch :: Exception e => IterT m a -> (e -> IterT m a) -> IterT m a #

MonadCont m => MonadCont (IterT m) # 

Methods

callCC :: ((a -> IterT m b) -> IterT m a) -> IterT m a #

(Functor m, Eq1 m) => Eq1 (IterT m) # 

Methods

(==#) :: Eq a => IterT m a -> IterT m a -> Bool #

(Functor m, Ord1 m) => Ord1 (IterT m) # 

Methods

compare1 :: Ord a => IterT m a -> IterT m a -> Ordering #

(Functor m, Show1 m) => Show1 (IterT m) # 

Methods

showsPrec1 :: Show a => Int -> IterT m a -> ShowS #

showList1 :: Show a => [IterT m a] -> ShowS #

(Functor m, Read1 m) => Read1 (IterT m) # 

Methods

readsPrec1 :: Read a => Int -> ReadS (IterT m a) #

readList1 :: Read a => ReadS [IterT m a] #

(Monad m, Traversable1 m) => Traversable1 (IterT m) # 

Methods

traverse1 :: Apply f => (a -> f b) -> IterT m a -> f (IterT m b) #

sequence1 :: Apply f => IterT m (f b) -> f (IterT m b) #

Monad m => Apply (IterT m) # 

Methods

(<.>) :: IterT m (a -> b) -> IterT m a -> IterT m b #

(.>) :: IterT m a -> IterT m b -> IterT m b #

(<.) :: IterT m a -> IterT m b -> IterT m a #

Monad m => Bind (IterT m) # 

Methods

(>>-) :: IterT m a -> (a -> IterT m b) -> IterT m b #

join :: IterT m (IterT m a) -> IterT m a #

Foldable1 m => Foldable1 (IterT m) # 

Methods

fold1 :: Semigroup m => IterT m m -> m #

foldMap1 :: Semigroup m => (a -> m) -> IterT m a -> m #

toNonEmpty :: IterT m a -> NonEmpty a #

Eq (m (Either a (IterT m a))) => Eq (IterT m a) # 

Methods

(==) :: IterT m a -> IterT m a -> Bool #

(/=) :: IterT m a -> IterT m a -> Bool #

(Typeable (* -> *) m, Typeable * a, Data (m (Either a (IterT m a))), Data a) => Data (IterT m a) # 

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> IterT m a -> c (IterT m a) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (IterT m a) #

toConstr :: IterT m a -> Constr #

dataTypeOf :: IterT m a -> DataType #

dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c (IterT m a)) #

dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (IterT m a)) #

gmapT :: (forall b. Data b => b -> b) -> IterT m a -> IterT m a #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> IterT m a -> r #

gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> IterT m a -> r #

gmapQ :: (forall d. Data d => d -> u) -> IterT m a -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> IterT m a -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> IterT m a -> m (IterT m a) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> IterT m a -> m (IterT m a) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> IterT m a -> m (IterT m a) #

Ord (m (Either a (IterT m a))) => Ord (IterT m a) # 

Methods

compare :: IterT m a -> IterT m a -> Ordering #

(<) :: IterT m a -> IterT m a -> Bool #

(<=) :: IterT m a -> IterT m a -> Bool #

(>) :: IterT m a -> IterT m a -> Bool #

(>=) :: IterT m a -> IterT m a -> Bool #

max :: IterT m a -> IterT m a -> IterT m a #

min :: IterT m a -> IterT m a -> IterT m a #

Read (m (Either a (IterT m a))) => Read (IterT m a) # 
Show (m (Either a (IterT m a))) => Show (IterT m a) # 

Methods

showsPrec :: Int -> IterT m a -> ShowS #

show :: IterT m a -> String #

showList :: [IterT m a] -> ShowS #

(Monad m, Monoid a) => Monoid (IterT m a) # 

Methods

mempty :: IterT m a #

mappend :: IterT m a -> IterT m a -> IterT m a #

mconcat :: [IterT m a] -> IterT m a #

Capretta's iterative monad

type Iter = IterT Identity #

Plain iterative computations.

iter :: Either a (Iter a) -> Iter a #

Builds an iterative computation from one first step.

runIter . iter == id

runIter :: Iter a -> Either a (Iter a) #

Executes the first step of an iterative computation

iter . runIter == id

Combinators

delay :: (Monad f, MonadFree f m) => m a -> m a #

Adds an extra layer to a free monad value.

In particular, for the iterative monad Iter, this makes the computation require one more step, without changing its final result.

runIter (delay ma) == Right ma

hoistIterT :: Monad n => (forall a. m a -> n a) -> IterT m b -> IterT n b #

Lift a monad homomorphism from m to n into a Monad homomorphism from IterT m to IterT n.

liftIter :: Monad m => Iter a -> IterT m a #

Lifts a plain, non-terminating computation into a richer environment. liftIter is a Monad homomorphism.

cutoff :: Monad m => Integer -> IterT m a -> IterT m (Maybe a) #

Cuts off an iterative computation after a given number of steps. If the number of steps is 0 or less, no computation nor monadic effects will take place.

The step where the final value is produced also counts towards the limit.

Some examples (n ≥ 0):

cutoff 0     _        ≡ return Nothing
cutoff (n+1) . returnreturn . Just
cutoff (n+1) . liftlift . liftM Just
cutoff (n+1) . delaydelay . cutoff n
cutoff n     neveriterate delay (return Nothing) !! n

Calling retract . cutoff n is always terminating, provided each of the steps in the iteration is terminating.

never :: (Monad f, MonadFree f m) => m a #

A computation that never terminates

untilJust :: Monad m => m (Maybe a) -> IterT m a #

Repeatedly run a computation until it produces a Just value. This can be useful when paired with a monad that has side effects.

For example, we may have genId :: IO (Maybe Id) that uses a random number generator to allocate ids, but fails if it finds a collision. We can repeatedly run this with

retract (untilJust genId) :: IO Id

interleave :: Monad m => [IterT m a] -> IterT m [a] #

Interleaves the steps of a finite list of iterative computations, and collects their results.

The resulting computation has as many steps as the longest computation in the list.

interleave_ :: Monad m => [IterT m a] -> IterT m () #

Interleaves the steps of a finite list of computations, and discards their results.

The resulting computation has as many steps as the longest computation in the list.

Equivalent to void . interleave.

Consuming iterative monads

retract :: Monad m => IterT m a -> m a #

retract is the left inverse of lift

retract . lift = id

fold :: Monad m => (m a -> a) -> IterT m a -> a #

Tear down a Free Monad using iteration.

foldM :: (Monad m, Monad n) => (m (n a) -> n a) -> IterT m a -> n a #

Like fold with monadic result.

IterT ~ FreeT Identity

class Monad m => MonadFree f m | m -> f where #

Monads provide substitution (fmap) and renormalization (join):

m >>= f = join (fmap f m)

A free Monad is one that does no work during the normalization step beyond simply grafting the two monadic values together.

[] is not a free Monad (in this sense) because join [[a]] smashes the lists flat.

On the other hand, consider:

data Tree a = Bin (Tree a) (Tree a) | Tip a
instance Monad Tree where
  return = Tip
  Tip a >>= f = f a
  Bin l r >>= f = Bin (l >>= f) (r >>= f)

This Monad is the free Monad of Pair:

data Pair a = Pair a a

And we could make an instance of MonadFree for it directly:

instance MonadFree Pair Tree where
   wrap (Pair l r) = Bin l r

Or we could choose to program with Free Pair instead of Tree and thereby avoid having to define our own Monad instance.

Moreover, Control.Monad.Free.Church provides a MonadFree instance that can improve the asymptotic complexity of code that constructs free monads by effectively reassociating the use of (>>=). You may also want to take a look at the kan-extensions package (http://hackage.haskell.org/package/kan-extensions).

See Free for a more formal definition of the free Monad for a Functor.

Methods

wrap :: f (m a) -> m a #

Add a layer.

wrap (fmap f x) ≡ wrap (fmap return x) >>= f

wrap :: (m ~ t n, MonadTrans t, MonadFree f n, Functor f) => f (m a) -> m a #

Add a layer.

wrap (fmap f x) ≡ wrap (fmap return x) >>= f

Instances

(Functor f, MonadFree f m) => MonadFree f (ListT m) # 

Methods

wrap :: f (ListT m a) -> ListT m a #

(Functor f, MonadFree f m) => MonadFree f (MaybeT m) # 

Methods

wrap :: f (MaybeT m a) -> MaybeT m a #

Functor f => MonadFree f (Free f) # 

Methods

wrap :: f (Free f a) -> Free f a #

Functor f => MonadFree f (F f) # 

Methods

wrap :: f (F f a) -> F f a #

Monad m => MonadFree Identity (IterT m) # 

Methods

wrap :: Identity (IterT m a) -> IterT m a #

(Functor f, MonadFree f m) => MonadFree f (ExceptT e m) # 

Methods

wrap :: f (ExceptT e m a) -> ExceptT e m a #

(Functor f, MonadFree f m, Error e) => MonadFree f (ErrorT e m) # 

Methods

wrap :: f (ErrorT e m a) -> ErrorT e m a #

(Functor f, MonadFree f m) => MonadFree f (IdentityT * m) # 

Methods

wrap :: f (IdentityT * m a) -> IdentityT * m a #

(Functor f, MonadFree f m, Monoid w) => MonadFree f (WriterT w m) # 

Methods

wrap :: f (WriterT w m a) -> WriterT w m a #

(Functor f, MonadFree f m, Monoid w) => MonadFree f (WriterT w m) # 

Methods

wrap :: f (WriterT w m a) -> WriterT w m a #

(Functor f, MonadFree f m) => MonadFree f (StateT s m) # 

Methods

wrap :: f (StateT s m a) -> StateT s m a #

(Functor f, MonadFree f m) => MonadFree f (StateT s m) # 

Methods

wrap :: f (StateT s m a) -> StateT s m a #

(Functor f, Monad m) => MonadFree f (FreeT f m) # 

Methods

wrap :: f (FreeT f m a) -> FreeT f m a #

MonadFree f (FT f m) # 

Methods

wrap :: f (FT f m a) -> FT f m a #

(Functor f, MonadFree f m) => MonadFree f (ContT * r m) # 

Methods

wrap :: f (ContT * r m a) -> ContT * r m a #

(Functor f, MonadFree f m) => MonadFree f (ReaderT * e m) # 

Methods

wrap :: f (ReaderT * e m a) -> ReaderT * e m a #

(Functor f, MonadFree f m, Monoid w) => MonadFree f (RWST r w s m) # 

Methods

wrap :: f (RWST r w s m a) -> RWST r w s m a #

(Functor f, MonadFree f m, Monoid w) => MonadFree f (RWST r w s m) # 

Methods

wrap :: f (RWST r w s m a) -> RWST r w s m a #

Examples