HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulefree-5.2Haskell2010

Control.Monad.Free.Ap

"Applicative Effects in Free Monads"

Often times, the (\<*\>) operator can be more efficient than ap. Conventional free monads don't provide any means of modeling this. The free monad can be modified to make use of an underlying applicative. But it does require some laws, or else the (\<*\>) = ap law is broken. When interpreting this free monad with foldFree, the natural transformation must be an applicative homomorphism. An applicative homomorphism hm :: (Applicative f, Applicative g) => f x -> g x will satisfy these laws.

  • hm (pure a) = pure a
  • hm (f <*> a) = hm f <*> hm a

This is based on the "Applicative Effects in Free Monads" series of articles by Will Fancher

  • 1 type
  • 1 class
  • 13 values
  • Packagefree-5.2
  • Exports15
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceAp.hs
classclass Monad m => MonadFree (f :: Type -> Type) (m :: Type -> Type) | 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
    
Instances18MonadFree, …
datadata Free (f :: Type -> Type) a
#

A free monad given an applicative

Constructors

Instances32MonadTrans, Generic1, MonadError, MonadReader, MonadState, MonadWriter, …
valueliftF :: (Functor f, MonadFree f m) => f a -> m a
#

A version of lift that can be used with just a Functor for f.

valueiter :: Applicative f => (f a -> a) -> Free f a -> a
#

Given an applicative homomorphism from f to Identity, tear down a Free Monad using iteration.

valuefoldFree
  1. :: (Applicative f, Monad m)
  2. => forall x. f x -> m x
  3. -> Free f a
  4. -> m a
#

Given an applicative homomorphism, you get a monad homomorphism.

valuecutoff :: Applicative f => Integer -> Free f a -> Free f (Maybe a)
#

Cuts off a tree of computations at a given depth. If the depth is 0 or less, no computation nor monadic effects will take place.

Some examples (n ≥ 0):

Property
cutoff 0     _        == return Nothing
Property
cutoff (n+1) . return == return . Just
Property
cutoff (n+1) . lift   ==   lift . liftM Just
Property
cutoff (n+1) . wrap   ==  wrap . fmap (cutoff n)

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

value_Pure
  1. :: (Choice p, Applicative m)
  2. => p a (m a)
  3. -> p (Free f a) (m (Free f a))
#

This is Prism' (Free f a) a in disguise

Example1 expression
preview _Pure (Pure 3)Just 3
Example1 expression
review _Pure 3 :: Free Maybe IntPure 3
value_Free
  1. :: (Choice p, Applicative m)
  2. => p (f (Free f a)) (m (f (Free f a)))
  3. -> p (Free f a) (m (Free f a))
#

This is Prism' (Free f a) (f (Free f a)) in disguise

Example1 expression
preview _Free (review _Free (Just (Pure 3)))Just (Just (Pure 3))
Example1 expression
review _Free (Just (Pure 3))Free (Just (Pure 3))