
Howdy! You all are probably wondering why this guide, when there are so many fine monad tutorials out there already. Well, I've noticed some people on the Haskell trail (and in the saloon) still talk of them monads like they were rattlesnakes hatched from a lawyer's briefcase. That just don't feel right! Actually, programming with monads is easy as branding cattle! So let's get started.
First, let's talk about prefix, infix and postfix. Suppose you want to put the argument of a unary function before the function (postfix).
flop :: a -> (a -> b) -> b
flop x f = f x
The flop function takes two arguments (binary) and any such function can be written as infix using the inverted quotes.
x `flop` f
You can write the composite of functions f, g and h (all unary and with the right types) as
x `flop` f `flop` g `flop` h
That ain't hard, but what about a function with two arguments (binary)? Well, as you know, in Haskell them kind of functions are treated like they was two unary functions (currying). So, because flop is defined for any type, you can write
x 'flop` y `flop` f
Let's try it out in Hugs or GHCi, with x and y type Double and division (/) for the binary function
3.0 `flop` 5.0 `flop` (/)
We get an error message
ERROR - Cannot infer instance
*** Instance : Fractional (a -> b)
*** Expression : flop (flop 3.0 5.0) (/)
Turns out I should have used brackets
3.0 `flop` (5.0 `flop` (/))
This works and gets 1.66666666666667 as answer in Hugs. But it's not what we want. The double flop changes f x y into y x f. We could use the Prelude function flip on (/) to get what we really, really want, which is x y f, but we won't do that. We'll use the lambda notation to force the result, using variable symbols.
3.0 `flop` (\x -> 5.0 `flop` (\y -> (x/y)))
So, can you define a function in this manner too? Sure, for example
divdbl :: Double -> Double -> Double
divdbl x y = x `flop`(\u -> y `flop` (\v -> (u/v)))
Now, I can imagine some of you are having trouble holding on to the fence, right now, 'cause you're laughing so hard. First I've used postfix notation for a function, then I needed the variables in lambda notation to get me out of a mess, and then I ended up with what I started with!
But the reason is, we're going to use this flop, or at least something like it, in a very general way in our monads. So, bear with me, even though it gets even crazier.

Them Haskell boys would rather ride out into a raging blizzard in their longjohns, than do any programming without types. So, let's get us a type
newtype Wrapped a = Wrap a
Usually the type constructor and the value constructor get the same name, but we want to show the distinction here. You wrap a value of type a to get a wrapped type a. So, the type signature of a wrapped divison of wrapped doubles would be
divwrp :: Wrapped Double -> Wrapped Double -> Wrapped Double
Now, can we use the definition of divdbl above unchanged? Let's try. No, we get an error from Hugs.
Instance of Fractional (Wrapped Double) required for definition of divwrp
Seems we can't divide wrapped doubles. We fix this problem by redefining our flop in two ways. Firstly the definition, of course, but secondly the type of our function f. To recall, we had
flop :: a -> (a -> b) -> b
flop x f = f x
Now we replace this with
wrflop :: Wrapped a -> (a -> Wrapped b) -> Wrapped b
wrflop (Wrap x) f = f x
Note the change, especially in f. The first argument, of type a, just becomes Wrapped a, and the result, which was type b, becomes Wrapped b. But f does not go from Wrapped a to Wrapped b, as you'd perhaps expect, but from a to Wrapped b.
Our function wrflop does not only change prefix to postfix, but also passes the unwrapped value of the argument to f, even though the argument itself is wrapped.
Now, some of you're smiling and bobbing your heads and nudging one another, 'cause you've heard this before. Monads are containers, right? Right!
Let's define a division function with wrapped doubles.
divwrp :: Wrapped Double -> Wrapped Double -> Wrapped Double
divwrp x y = x `wrflop`(\u -> y `wrflop` (\v -> (Wrap (u/v))))
Note the Wrap value constructorat the end, which you need to get a Wrapped result.
Run, with Hugs or GHCi
divwrp (Wrap 3.0) (Wrap 5.0)
Hugs gives an error message
ERROR - Cannot find "show" function for:
*** Expression : divwrp (Wrap 3.0) (Wrap 5.0)
*** Of type : Wrapped Double
All right, that's just about displaying the result. We fix this with
instance Show a => Show (Wrapped a) where
show (Wrap a) = "Wrapped: " ++ (show a)
Now the result from Hugs is
Wrapped: 0.6
Just to recall, Show is the Class of all types which can be shown, that is, for which the show function, which evaluates to a String, can be defined. The actual definition for any particular type is done in an instance definition of Show.
Here we assume that the show function has already been defined for the particular type a. So all we have to do is give a definition for types Wrapped a.
Before we ride out to get us some monads there's one other thing we'd better look at first. Usually, you don't want to show the evaluation as a wrapped or monadic type, but you'll want the unwrapped result.
The old Haskell hands have a trick for this, which is to use named fields in their data and type definitions. (Recall that a newtype definition is just like a data definition, but with no choice operator (|). A newtype has only one value constructor.)
So we'll redefine our Wrapped type
newtype Wrapped a = Wrap {unwrap :: a}
This has nothing to do with monads, but the named field is automatically implemented as an accessor function to the Wrapped type. So now, without defining the show function, you can use for the wrapped division
unwrap (divwrp (Wrap 3.0) (Wrap 5.0))
This gives the expected value 0.6

Now, I don't blame you for fidgeting and looking at them horses suspiciously, 'cause you're starting to smell manure, right? You haven't heard one useful thing yet, is what you're thinking. Bear with me.
This Wrapped type constructor, which can Wrap any type you like, can itself be parametrized. So now you have sort of twofold polymorphism, first for your type constructor and second for your type. Now, if a type constructor is one of them monads, you can say so with
Class Monad m where
and next you specify what's at least needed for such a type constructor to be a Monad.
Recall the Show Class we had earlier. This says what is needed for a type to be a member of that class, which is just that there is a function show which takes something of that type as argument, and has a String as its value.
What the function actually is depends on the type, and you specify that in an instance definition. With Monads it's the same, but the variable m is not a type. Recall that each type in Haskell has the same kind (yep, kind of super type) denoted by * . A type constructor takes a kind and returns a kind, so its supertype is * -> * . Now Monad is just the Class of them type constructors. When is a type constructor a monad?
Class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
That's it, really. Now look at the wrflop function above. Get it? The directed fish hook, which, by the way, you should call 'bind', so's not to look foolish, reverts the postfix notation and hooks the value out of the container. Thirdly, and that's the useful part, the bind can do something different for each different Monad. All this must be implemented in an instance, of course. The class just provides the type signature.
Look at the divwrp function again, and note the actual division result had to be wrapped, for type consistency. We generalize this too, and it's called return
return :: a -> m a
You'll get the idea of returning the result, which is at the end, in the right type, but keep in mind the return is not like a return in an imperative language like C, or something.
Thirdly, in our Monad class, we have
(>>) :: m a -> m b -> m b
(>>) (m x) (m y) = (>>=) (m x) (\_ -> m y)
You might also see
m >> k = m >>= \_ -> k
Don't let this throw you out of the saddle! Substitute m for (m x) and k for (m y) and look at the infix and prefix positions, and you'll see the two definitions are the same. It just means x >> y evaluates to y. Why in the heck would anyone want to use that? Well, it's when monads are used to model actions, like in input/output. Then you might want to use a second monadic expression while disregarding the result of the first. We'll get to that.
Lastly, there's a fail function, which is used sometimes, but not often.
fail :: String -> m a
fail s = error s
Though we'll ramble around this, note that apparently the well known error function returns a monadic type! Note the fail can be overridden in an instance definition. Also keep in mind the bind and return must obey certain laws, for the definition to work. For the monads in the GHC library you can assume this has been checked, of course, but if you roll your own....look at the list example we'll be talkin' about later.
All right, all right...we'll get us a monad, real soon now, though y'all will probably be disappointed. It don't do much at all, no sir! But first the do notation, forgive the pun. Bear with me.

Cause you're all so impatient we'll skip the pattern matching in the do notation. The simple case is where we only have names before the arrow. Then
do x <- e1; e2; ...; en
evaluates to
e1 >>= \x -> do e2;...;en
So, it's essentially a sequence of binds. Recall the definition of (>>). Now you see how that seamlessly fits in.
You can also have a let in a do notation. It's defined as
do let decllist; e2;...; en
which evaluates to
let decllist in do e2;...;en
So you don't need the keyword in in a monadic do notation, as you're used to with the usual function definitions. It's already part of the syntactic sugar.
Now, at last, the first monad. Define the type
newtype Wrapped a = Wrap {unwrap :: a}
Define the bind and return as Monad instances
instance Monad Wrapped where
(>>=) (Wrap x) f = f x
return x = Wrap x
Note the fishhook is just our wrflop and the return is just our Wrap value constructor. But now we can rewrite our wrapped division in monadic do notation
divwrp :: Wrapped Double -> Wrapped Double -> Wrapped Double
divwrp x y = do u <- x
v <- y
return (u/v)
Run it in Hugs
unwrap (divwrp (Wrap 3.0) (Wrap 5.0))
This gives us the usual result 0.6. Note we still need the unwrap accessor function to get the value out of the Wrapped type.

Our Wrapped monad is actually the Identity monad, as defined in the Control.Monad.Identity GHC module. It don't do much, but now we're ready for some useful monads! All you have to do is define your binds and returns (keeping the laws in mind). Many have already been defined in modules, or even the prelude.
Maybe
data Maybe a = Nothing | Just a
instance Monad Maybe where
(>>=) Nothing f = Nothing
(>>=) (Just x) f = f x
return x = Just x
The Maybe data type is for functions that might not always work out, like looking for things in a list, or floating point calculations which are not accurate enough for some arguments. But what if the arguments themselves could or could not be of type Maybe?
If an argument itself is Nothing, it makes sense to define the result of the function Nothing too, right away. That's what the bind does. If the argument is Just x, the bind hooks the x out of the container and passes it to the function. The return constructs the Maybe value from a value. It can only be Just a.
divsumdif:: Double -> Double -> Maybe Double
divsumdif x y | abs (x - y) <= 1.0e-4 = Nothing
| otherwise = Just ((x +y) / (x - y))
onediv :: Double -> Maybe Double
onediv x | x >= 1.0e+5 || x <= 1.0e-5 = Nothing
| otherwise = Just (1.0 / x)
composediv :: Double -> Double -> Maybe Double
composediv x y = do u <- onediv x
v <- onediv y
divsumdif u v
Running Hugs
composediv (1.0/6.0) (1.0/4.0)
Just 5.0
composediv 1.0e6 4.0
Nothing
Note the Maybe type apparently already has its show function defined in the Prelude. Also note the absence of the return function in the example.
Suppose you want divsumdif, knowing there is a possible inaccuracy in the first argument, but the second one is allright.
oneokcompose :: Double -> Double -> Maybe Double
oneokcompose x y = do u <- onediv x
divsumdif u y
Hugs
oneokcompose (1.0/6.0) 4.0
Just 5.0
oneokcompose 1.0e6 4.0
Nothing
oneokcompose (1.0/4.0) 4.0
Nothing

State s
newtype State s a = State { runState :: (s -> (a,s)) }
instance Monad (State s) where
(>>=) (State x) f = State (\st -> let (v,ns) = x st in runState (f v) ns )
return x = State (\s -> (x,s))
How `bout that? Bet you Java slickers ain't seen nothing like this before! No, sir! But recall monadic computation is just function composition in postfix form with some type trickery. As an aside, them tricks are supposed to keep folks from shootin' themselves in the foot. That's the reason, though it might look strange. But let's move on.
A function which uses state is just a function from a type a to a type b, but the result also depends on something else, a state. Secondly, the function can change the state. In functional programming you never change anything, but of course you can get a new state as a function result. So a stateful function itself, before even thinking of a monad, is of type
f :: a -> s -> (b,s)
It's a binary function which evaluates to a tuple. Get it? If you take the first argument only, the result is a function which takes a state and returns a tuple. It's just currying. Now you wrap this up in a State. That's your definition of the return.
Look at the newtype definition. This is also kind of binary, right? State s a, with s and a of a certain type, is a type. So (State s) is a type constructor. State is also a type constructor, which evaluate to a type constructor. It's just currying with types. But your monad m a is now monad State s a so you need State s and not State in your instance definition.
The bind function, the fish hook. What does it do? Well, it converts (m x) f to f (m x) and gives the x to f. That's the same for all monads. Looking again at the type signature for bind in the Monad Class definition, we see the that x >>= f, for this instance, evaluates to type
State (\s -> (a,s))
In this case x is a function, which takes an s and gives a tuple (a,s), so that's what we use in the definition
State (\st -> let (v, ns) = x st in ......)
Here v is the value of type a, ns is the new state of type s.
These two are the arguments of our binary function f. But this is of type
a -> State ( s -> (b,s))
So you have f v, where value v is of type a. But now, to apply this to argument ns, you must first use the accessor function runState. So you get
(>>=) (State x) f = State (\st -> let (v,ns) = x st in runState (f v) ns )
Define a function which turns a character into upper or lower case, depending on a state of true or false. You need module Data.Char for this.
chncase :: Char -> Bool -> (Char, Bool)
chncase x s | s == True = ((toLower x), False)
| otherwise = ((toUpper x), True)
With Hugs
chncase 'a' True
('a',False)
chncase 'a' False
('A',True)
chncase 'A' True
('a',False)
chncase 'A' False
('A',True)
chncase 'A'
ERROR - Cannot find "show" function for:
*** Expression : chncase 'A'
*** Of type : Bool -> (Char,Bool)
Note that the error just refers to the show function. Taking just one argument returns a perfectly valid Haskell type.
Redefine the function as a State monad.
chncasewst :: Char -> State Bool Char
chncasewst x = State (\st -> chncase x st)
Note we've done nothing, except redefine the function with one argument only, and put the State value constructor in front for type correctness. But now we can use our monad definition of bind and return to compose the function.
chncasewst3 :: Char -> Char -> Char -> State Bool String
chncasewst3 x y z = do u <- chncasewst x
v <- chncasewst y
w <- chncasewst z
return [u,v,w]
Look at the type declaration. It's a function, which takes a Char, evaluates to a function which takes a Char, evaluates to a function which takes a Char, evalutes to a State Bool String. This, however, is a function which takes a Bool and evaluates a Char, Bool tuple. Just for fun, let's rewrite chncasewst3 with the fish hooks.
chncasewst3 :: Char -> Char -> Char -> State Bool String
chncasewst3 x y z = (chncasewst x) >>= (\u ->
(chncasewst y) >>= (\v ->
(chncasewst z) >>= (\w ->
return [u,v,w] )))
Note it's just postfix composition, with the fish hook doing the work. To actually get some result from this all, keep in mind it's of type State Bool String. So, as always, you'll have to use the accessor function. If you have not used a named field for your newtype definition, you'll have to write something yourself. In this case the content of the result is itself a function, which takes a Bool argument.
So, with Hugs or GHCi
runState (chncasewst3 'e' 'd' 'f') False
("EdF",True)
runState (chncasewst3 'E' 'D' 'F') False
("EdF",True)
runState (chncasewst3 'E' 'D' 'F') True
("eDf",False)
Of course, to clean it up, you could write
altcase3 :: Char -> Char -> Char -> Bool -> String
altcase3 x y z tof = charstr where
(charstr, _) = runState (chncasewst3 x y z) tof
With Hugs
altcase3 'd' 'e' 'f' True
"dEf"
altcase3 'd' 'e' 'f' False
"DeF"

Now, in this example all the arguments were of the same type. Course it don't have to be that way, so long as you use the correct types in your composition. But if they are of the same type, like here, you can map them monadic functions to a list, like any other function. Then there's a special function in the Prelude, called 'sequence', which will insert all the binds for you. In fact, this is so common, there's a function mapM which does both.
Have another look at
chncasewst :: Char -> State Bool Char
chncasewst x = State (\st -> chncase x st)
Checking the type of mapM with Hugs
:t mapM
mapM :: Monad a => (b -> a c) -> [b] -> a [c]
So let's define
altcasestring :: String -> State Bool String
altcasestring str = mapM chncasewst str
With Hugs
runState (altcasestring "abcdefg") True
("aBcDeFg",False)
runState (altcasestring "abcdefg") False
("AbCdEfG",True)
As before, you'd probably put the runState inside yet another function which will take a String and a Boolean and evaluate to a String
altstring2string :: String -> Bool -> String
altstring2string str tof = altstr where
(altstr, _) = runState (altcasestring str) tof
Hugs
altstring2string "ABCDEFG" True
"aBcDeFg"
altstring2string "ABCDEFG" False
"AbCdEfG"
There's lots more functions and tricks, so you monad cowboys just better look for 'em and start practicing! Yes, Sir! Meanwhile, here's another monad for you.

[]
the standard Haskell list
instance Monad [] where
(>>=) [x] f = concatMap f [x]
return x = [x]
If you're still thinking of monads as special things, now 's the time to change your ways. The return function takes something of a type a to a list of type a. The function f takes something of type a to a list of type b. This is all in the general Monad Class declaration. The bind here is the standard concatMap function on lists, but in postfix notation.
The instance definition is already in the Prelude, so you can use monadic notation straight away.
cross :: [a] -> [b] -> [(a,b)]
cross ls1 ls2 = do x <- ls1
y <- ls2
return (x,y)
Well, this does demonstrate a disadvantage of using the same symbols for all those different monads (overloading). You must keep track of what your code means when it all looks the same.
Hugs
cross "AB" [1,2,3]
[('A',1),('A',2),('A',3),('B',1),('B',2),('B',3)]
So the cross function evaluates to the Cartesian product. Another way to do this would be with list comprehension
cross :: [a] -> [b] -> [(a,b)]
cross ls1 ls2 = [ (x,y) | x <- ls1, y <- ls2 ]
Hugs
cross "AB" [1,2,3]
[('A',1),('A',2),('A',3),('B',1),('B',2),('B',3)]
Don't let the similarities in the two definitions confuse you. The use of the arrows is just another case of symbol overloading in the Haskell programming language. List comprehension is not monadic.
Let's use the list monad to examine the monad laws mentioned earlier. Each instance of the monad class has to comply with
(m x) >>= f >>= g = (m x) >>= (\y -> f y >>= g)
(>>=) (return x) f = f x
(>>=) (m x) return = m x
What does this mean? Define two functions (you need module Data.Char for this)
f :: Char -> [Int]
f x = [ord x, ord x]
g:: Int -> [Char]
g y = [chr y, chr y]
These are of the right monadic type. Monadic composition with the bind
gf1 :: [Char] -> [Char]
gf1 ls = ls >>= f >>= g
In do notation
gf1 :: [Char] -> [Char]
gf1 ls = do x <- ls
y <- f x
g y
Both versions clearly show the composition, but for the do notation you use self named variables. Hugs gives
gf1 "abc"
"aaaabbbbcccc"
The function gf1 quadruples each element in the list, but, just to demonstrate the use of different types in a monadic computation, through the intermediate ord function.
So, what does the notation
(\y -> f y >>= g)
stand for?
cfg :: Char -> [Char]
cfg x = (f x) >>= g
gf2 :: [Char] -> [Char]
gf2 ls = ls >>= (\y -> cfg y)
In do notation
gf2 :: [Char] -> [Char]
gf2 ls = do x <- ls
cfg x
Hugs
gf2 "abc"
"aaaabbbbcccc"
So, the first monadic law above states that functions like gf1 and gf2 must always evaluate to the same result. Monadic composition is associative.
The two laws with the return just say you can slap 'em on at the beginning and the end, even when they're not needed. A return is kind of an identity in monadic composition. So you can write
fm1 :: Char -> [Int]
fm1 x = do u <- return x
f u
fm2 :: Char -> [Int]
fm2 x = do u <- f x
return u
Hugs
fm1 'a'
[97,97]
fm2 'a'
[97,97]
f 'a'
[97,97]
The return is like an identity function for monadic composition.

Reader e
newtype Reader e a = Reader { runReader :: (e -> a) }
instance Monad (Reader e) where
return x = Reader (\e -> x)
(Reader x) >>= f = Reader (\e -> runReader (f (x e)) e)
If you're still wondering about the State monad, look at this one. It's also for a function of some type a which evaluates to a type b, but depends on a second argument. Other than with State, however, this second argument does not change when the function is evaluated. The function just reads it. That's why it's called the Reader monad, and the second argument is often referred to as environment.
Because it's so much like state we'll use almost the same example.
chncase :: Char -> Bool -> Char
chncase x e | e == True = toLower x
| otherwise = toUpper x
Because e is not changed, we don't have to put it into the result. The next step is to convert this into a function which evaluates to a Reader Bool Char type.
chncasewrd :: Char -> Reader Bool Char
chncasewrd x = Reader (\e -> chncase x e)
Now we can define a monadic composition
chncasewrd3 :: Char -> Char -> Char -> Reader Bool String
chncasewrd3 x y z = do u <- chncasewrd x
v <- chncasewrd y
w <- chncasewrd z
return [u,v,w]
Hugs
runReader (chncasewrd3 'A' 'B' 'c') True
"abc"
runReader (chncasewrd3 'A' 'B' 'c') False
"ABC"
The rest is left as an exercise to the reader. Sorry, just horsin' around...
There are some helper functions which might come in handy.
ask :: Reader e e
ask = Reader id
runReader ask is a function which takes something of type e and returns something of type e. If that function is id, the identity function, the result will be the environment itself.
Hugs
runReader ask [1,2,3]
[1,2,3]
Often you have a function from the environment, typically some lookup function, like the standard one from the Prelude.
asks :: (e -> a) -> Reader e a
asks sel = ask >>= return . sel
Hugs
runReader (asks $ lookup 2) [(1,'a'),(2,'b'),(3,'c')]
Just 'b'
You might want to change the environment.
local :: (e -> e) -> Reader e a -> Reader e a
local f c = Reader (\e -> runReader c (f e))
Here f e is the new environment to apply the Reader on. Actually, these three functions are defined in the GHC library as instances of a derived class, which is more general, but we don't care about that here.
Some more horsin' around now, just to show how it works. We'll use sample as the environment.
sample :: [(String, Int)]
sample = [("count",3), ("1",1), ("b",2)]
The following function uses lookup "count" to get the Int 3. The result is a Maybe, so we have to check for Nothing and get the value from Just. Note the use of fail from the monad class definition, which defaults to error. The last line of the function returns the result of the comparison of cnt and the length of the list.
countcorrect :: Reader [(String,Int)] Bool
countcorrect = do maybecnt <- asks (lookup "count")
let ok (Just x) = return x
ok _ = fail "countcorrect: lookup failed"
cnt <- ok maybecnt
env <- ask
return (cnt == (length env))
Hugs
sample
[("count",3),("1",1),("b",2)]
runReader countcorrect sample
True
runReader countcorrect [("1",1),("b",1)]
Program error: countcorrect: lookup failed
The next function illustrates the use of local. The function of type (e -> e) is the function (("c",3) :), which adds the element ("c",3) to the front of the list.
newcountcorrect :: Reader [(String,Int)] Bool
newcountcorrect = local (("c",3) :) countcorrect
Now the length of the new (local) environment list is 4, so newcountcorrect returns False.
runReader newcountcorrect sample
False
Since Reader and State are so similar, you might wonder if there are also helper functions defined for State monads. Yes, there are.
get :: State s s
get = State (\s -> (s,s))
put:: s -> State s ()
put s = State (\_ -> ((),s))
The first one evaluates to a tuple (s,s) when given a state s. The second one is a function which can take anything, and then will have s as the second value of the tuple. The () is the unit type, which is a sort of void, or null or noop. Again, these functions can be defined as instances of special classes, but we don't care here. Of course, if you run into trouble with my definitions, just import the standard modules you want. I won't mind. No, sir. Fact is, I recommend it!
An example of the use of get and put
tick :: State Int Int
tick = do n <- get
put (n+1)
return n
Hugs
runState tick 5
(5,6)
Cleaning up the tick
increment :: Int -> Int
increment n = snd $ runState tick n
Hugs
increment 5
6

Well, we could go on like this for some more time, I suppose, because there's many more monads, but I figure enough is enough. Except for the IO Monad, that is.
Try Hugs
:t getLine
getLine :: IO String
:t putStrLn
putStrLn :: String -> IO ()
:t putStr
putStr :: String -> IO ()
Now, what the heck is goin' on here? Well, there's a problem with things that do more than just evaluate, in functional programming. Take putStrLn and putStr, for example. They take the same input type, but where's the output? It's out, that's where! So how do you express the difference, that is that one adds a newline and the other does not? Answer, you can't!
But using monads allows you to model actions just like they were functions. Recall the trouble we had getting the value out of the State monad? Well, with the IO monad you can't get the value. Actually IO uses a token which is passed, but this is made invisible to the user. But now you can do all input and output inside the same type, and all other functions, including the monadic ones, are protected from type errors.
module Main where
main :: IO ()
main = do putStrLn "Enter a string:"
str <- getLine
let nwstr = reverse str
putStrLn nwstr
The type of the action, inside the IO () , is the unit type. As mentioned before, it's similar to void, null, noop or whatever.
Hugs
main
Enter a string:
danoM
Monad
Rewrite with the bind operator
main :: IO ()
main = putStrLn "Enter a string:"
>> getLine
>>= (\str -> let newstr = reverse str
in putStrLn newstr)
Hugs
main
Enter a string:
danoM
Monad
Recall the default definition of the (>>) operator in the general Monad Class declaration? Here's an example of its use. The action getLine, of type IO String, does not operate on the putStrLn before, which outputs the user prompt. The getLine binds the next function, though, which is the putStrLn which outputs that argument variable. In between you have the pure functional part, which reverses the string. So, the IO monad allows for a very clear separation between input/output and the rest. Of course, normally you wouldn't use the let for this, but
module Main where
main:: IO ()
main = do putStrLn "Enter a string:"
str <- getLine
putStrLn (reverse str)
The result is the same, and you still have a clear separation of your functions and the input of arguments and the output of evaluations. And because the IO monad can have anything for its inner type, and these have to be correct, you have input/output with all the usual type checking facilities from Hugs and GHC.
You might wonder, why the main all of a sudden? No 'special reason, but how many functions are you going to have, which take no arguments and evaluate to the unit type? But you could define the same action as useraction, or anything else, if you like. More useful would be another action, or function, which gets you the string.
userrev :: IO String
userrev = do putStrLn "Enter a string:"
str <- getLine
return (reverse str)
Hugs
userrev :: IO String
Enter a string:
Monad
It runs all right, but it won't give you an answer! You can't get the string out of the IO wrapper! What you can do
main:: IO ()
main = userrev >>= putStrLn
Look at the bind. It does exactly what it's supposed to do, it changes the postfix to prefix and takes the String argument out of the IO String. Now the putStrLn can use it.
Hugs
main
Enter a string:
Monad
danoM

Well, y'all know, that if you put a horse and a donkey together, of opposite genders, at the right place and the right time, you might get yourself a mule. Which is a good thing, because that mule will have the characteristics of both a horse and a donkey!
Monads that can take another monad in such a way, that the results are combined, are called monad transformers. Any monad is of type m a , and of course the general type a can itself be monadic, say m2 b . Now a monad transformer is defined in such a way, that it works on the value of the inner monad, b , and not just the m2 b . To distinguish such a monad transformer from its simpler cousin, it's called the same, but with a T at the end. So, you have State and StateT, Reader and ReaderT, and so on. Note that this is just by convention of the library writers, you can call them anything you like. The definition of each monad transformer can be different, and not all monads have a transformer. But monad transformers are monads, so they can be defined in the usual way. We'll take StateT as an example.
StateT s m
newtype StateT s m a = StateT { runStateT :: (s -> m (a,s)) }
instance (Monad m) => Monad (StateT s m) where
return a = StateT (\s -> return (a,s))
(StateT x) >>= f = StateT ( \s -> do (v,ns) <- x s
(StateT nx) <- return (f v)
nx ns )
The type constructor is like the one for State, but with one extra parameter. Note that the type definition places the tuple inside the inner monad, not the first element of that tuple. In general each different monad transformer uses its own type definition. There is no general structure or design pattern for monad transformers.
The bind and return definitions of StateT use the bind and return of the inner monad, here with the do notation. The return is just like the one for State, but it takes the return of monad m as its parameter. The bind should be read the same way. Again x is a function, running it will evaluate to m (v,ns), therefore (v,ns) is the parameter in the lambda notation. The function takes the value v, the return makes it a monad, and value constructor StateT takes it to the right type. Now the function nx takes parameter ns. Yes sir! Sure looks like a monad rodeo trick to me, but greenhorns can use it easily. I'll show ya.
We'll use the same basic function as with State, but now we'll check if the character is a letter. We use Maybe, which is a monad. The function was
chncase :: Char -> Bool -> (Char, Bool)
chncase x s | s == True = ((toLower x), False)
| otherwise = ((toUpper x), True)
The new version is
mbcase :: Char -> Bool -> Maybe (Char, Bool)
mbcase x s | isAlpha x = Just (chncase x s)
| otherwise = Nothing
Adapt this for use in StateT
mbcasewst :: Char -> StateT Bool Maybe Char
mbcasewst x = StateT (\st -> mbcase x st)
Now we can use monadic function composition
mbcasewst3 :: Char -> Char -> Char -> StateT Bool Maybe String
mbcasewst3 x y z = do u <- mbcasewst x
v <- mbcasewst y
w <- mbcasewst z
return [u,v,w]
Hugs
runStateT (mbcasewst3 'a' 'b' 'c') True
Just ("aBc",False)
runStateT (mbcasewst3 'a' 'b' 'c') False
Just ("AbC",True)
runStateT (mbcasewst3 '1' 'b' 'c') True
Nothing
runStateT (mbcasewst3 'a' 'b' '3') True
Nothing
runStateT (mbcasewst3 '1' 'b' '3') True
Nothing
You can use mbcasewst on a list and define everything like an ordinary function
mbaltstr :: String -> Bool -> Maybe String
mbaltstr str tof = case (runStateT (mapM mbcasewst str) tof) of
Nothing -> Nothing
Just (rstr,_) -> Just rstr
Hugs
mbaltstr "abcdefg" True
Just "aBcDeFg"
mbaltstr "abcdefg" False
Just "AbCdEfG"
mbaltstr "abc4efg" True
Nothing
StateT also has helper functions put and get
get :: (Monad m) => StateT s m s
get = StateT (\s -> return (s,s))
put :: (Monad m) => s -> StateT s m ()
put s = StateT (\_ -> return ((),s))
They're very similar to the ones for State. So similar, in fact, their signatures are declared in a MonadState class in the standard library, with the actual definitions as instances of that same MonadState class. Other monads, like Reader and ReaderT, also use an intermediate class. These definitions, however, depend on non Haskell 98 features, and are somewhat complicated by themselves, so I've just skipped that part here. But be aware, when you're using the standard library documentation, that they've done it that way.
There's a generalized function to let you use a monad in a monad transformer
class MonadTrans t where
lift :: (Monad m) => m a -> t m a
Its definition for StateT is
instance MonadTrans (StateT s) where
lift c = StateT ( \s -> c >>= (\x -> return (x,s)))
Note that it just puts the state it's given into the StateT value (this makes sense, when you think about it). But lift is widely used with monad transformers, and even with StateT it can have its use. Suppose you have
mbexcl :: Char -> Maybe Char
mbexcl x | x == '!' || x == '?' = Just x
| otherwise = Nothing
Now, using lift, you can use this in our example
mbcasewst4 :: Char -> Char -> Char -> Char -> StateT Bool Maybe String
mbcasewst4 x y z ec = do u <- mbcasewst x
v <- mbcasewst y
w <- mbcasewst z
p <- lift (mbexcl ec)
return [u,v,w,p]
Hugs
runStateT (mbcasewst4 'a' 'b' 'c' '?') True
Just ("aBc?",False)
runStateT (mbcasewst4 'a' 'b' 'c' '4') True
Nothing
runStateT (mbcasewst4 'a' 'b' 'c' 'd') True
Nothing

Well, folks, that's about it. We've come to the end. Of course, if y'all wanna be real monad cowboys, there's more, and this has just been a start. But I hope you understand, by now, that them monads aren't rattlesnakes which, given half a chance, are goin' to rear up their heads and bite you. What the heck, I even overheard one trail boss referring to them as warm, furry things...well, now! But them Haskell boys have defined many useful monads and remember, you can define one yourself, with a return and a bind, just in a few lines. You can even breed with monads to get new combinations. You can use all the notation and all the monad functions that already 've been prepared for ya. So, thinkin' again, maybe them monads are warm and furry after all! Yes Sir, maybe they are!

The text of this tutorial was written by Hans van Thiel, in August/September 2008, and made available under the simple permissive license , as if it were on the Haskell Wiki. Thanks to everybody whose ideas I've used, especially the authors of other tutorials, from which I've learned myself.
The western graphics are from
and the author is much obliged!
Last updated September 7, 2008