[Haskell-beginners] Are monads pure?
Stephen Tetley
stephen.tetley at gmail.com
Tue May 18 04:24:17 EDT 2010
On 18 May 2010 05:37, Amy de Buitléir <amy at nualeargais.ie> wrote:
[SNIP]
>> [aditya siram]
>> With a monad you can
>> 1. takes some data and wraps it up in a type (return) :
>> a -> m a
>> 2. apply a function to the data within the type (>>=).
>> m a -> (a -> m b) -> m b
>
>
> But if that's all you need to do, you could just use an Applicative Functor,
> right? The picture I have at the moment is:
>
> Functors can apply a function to a value inside a container.
>
> Applicative functors provide pure expressions and sequencing, but no
> binding. All applicative functors are also functors.
Hello all
With bind, monads are a more powerful than applicative functors as
they give you the ability to perform context sensitive operations
whereas you could consider Applicative functors to be "context-free".
This means you can write more control operations for monads than
applicative functors, for instance you can have a State applicative
functor just as you can have a State monad. However with just
applicative you can't write the useful bracket function, which first
takes a snapshot of the state, performs the stateful function, then
restores the original state:
> newtype State st a = State { getStateF :: st -> (a,st) }
Functor instance:
> instance Functor (State st) where
> fmap f (State sf) = State $ \st ->
> let (a,st1) = sf st in (f a,st1)
Applicative instance
> instance Applicative (State st) where
> pure a = State $ \st -> (a,st)
> (State sfab) <*> (State sf) = State $ \st ->
> let (fab,st1) = sfab st
> (a, st2) = sf st1
> in (fab a,st2)
Monad instance
> instance Monad (State st) where
> return a = State $ \st -> (a,st)
> (State sf) >>= smf = State $ \st ->
> let (a1,st1) = sf st1
> sfun = getStateF (smf a1)
> (a2,st2) = sfun st2
> in (a2,st2)
> get :: State a a
> get = State $ \st -> (st,st)
> put :: a -> State a a
> put a = State $ \ _st -> (a,a)
> mbracket :: State st a -> State st a
> mbracket ma = do { st <- get
> ; ans <- ma
> ; put st
> ; return ans
> }
Or without the do notation:
> mbracket' :: State st a -> State st a
> mbracket' ma = get >>= \st ->
> ma >>= \ans ->
> put st >>= \_ -> return ans
No bracket with just the applicative machinery...
More information about the Beginners
mailing list