
When I first started learning Haskell, I was under the impression that monads provided a way to encapsulate some imperative code so it didn't "contaminate" your functional code. But I think that's a misconception that I got because the first monad I dealt with was IO. Lately I've been reading more about monads, and (aside from IO), they are purely functional, aren't they? If they have state, they deal with it in a purely functional way. Behind the scenes, they thread the state through your computations so that you don't you don't have to bother with it. Is that correct? TIA.

Threading state is something that the State monad does and it is
purely functional - showing that a monad *can* be pure but don't have
to be. Other monads, like IO as you have stated, have side effects.
At the end of the day I found that the monad is very, very general and
it's best way to think about it as a piece of data wrapped in some
type. 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
hth,
-deech
On 5/17/10, Amy de Buitléir
When I first started learning Haskell, I was under the impression that monads provided a way to encapsulate some imperative code so it didn't "contaminate" your functional code. But I think that's a misconception that I got because the first monad I dealt with was IO. Lately I've been reading more about monads, and (aside from IO), they are purely functional, aren't they? If they have state, they deal with it in a purely functional way. Behind the scenes, they thread the state through your computations so that you don't you don't have to bother with it. Is that correct? TIA.

Threading state is something that the State monad does and it is
purely functional - showing that a monad *can* be pure but don't have to be. Other monads, like IO as you have stated, have side effects.
Thank you, that helps.
At the end of the day I found that the monad is very, very general and it's best way to think about it as a piece of data wrapped in some type. 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. Arrows provide a way to set up more complicated pipelines with "tee" junctions, etc. All arrows are also applicative functors (?) Monads add binding. All monads are also arrows.

On 18 May 2010 05:37, Amy de Buitléir
[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...

When I first started learning Haskell, I was under the impression that monads provided a way to encapsulate some imperative code so it didn't "contaminate" your functional code. But I think that's a misconception that I got because the first monad I dealt with was IO. Lately I've been reading more about monads, and (aside from IO), they are purely functional, aren't they? If they have state, they deal with it in a purely functional way. Behind the scenes, they thread the state through your computations so that you don't you don't have to bother with it. Is that correct? TIA.
You are right. IO is an exception, because it is a built-in type that cannot be implemented in Haskell itself. Monads that are implemented in Haskell without mentioning IO or interfacing via the FFI are generally pure. Examples are state, errors, reader/writer, continuations, lists, ... Nevertheless, people often refer to features such as state and exceptions as "effects", and hence sometimes call code that makes use of them "effectful" and code that does not "pure". Cheers, Andres -- Andres Loeh, Universiteit Utrecht mailto:andres@cs.uu.nl mailto:mail@andres-loeh.de http://www.andres-loeh.de

Andres Loeh wrote:
Nevertheless, people often refer to features such as state and exceptions as "effects", and hence sometimes call code that makes use of them "effectful" and code that does not "pure".
This makes sense if you think of monads as embedded domain specific languages. In the jargon of, say the DSL corresponding to the state monad, the operation put has an "effect". But the embedding into Haskell maps put to a pure function of type s -> ((),s) . Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com
participants (5)
-
aditya siram
-
Amy de Buitléir
-
Andres Loeh
-
Heinrich Apfelmus
-
Stephen Tetley