[Haskell-cafe] The essence of my monad confusion

Antoine Latter aslatter at gmail.com
Sat May 2 12:51:49 EDT 2009

On Sat, May 2, 2009 at 11:31 AM, Paul Keir <pkeir at dcs.gla.ac.uk> wrote:
> On the wiki page for Applicative Functors
> (http://www.haskell.org/haskellwiki/Applicative_functor) a familiar
> characteristic of monads is quoted; that they "allow you to run actions
> depending on the outcomes of earlier actions". I feel comfortable with
> Functors and Applicative Functors, but I don't yet get that "extra power"
> that monads provide.
> An example immediately follows that quotation on the wiki:
> do text <- getLine
>    if null text
>      then putStrLn "You refuse to enter something?"
>      else putStrLn ("You entered " ++ text)
> For simplicity's sake, I modified it to avoid using the IO monad; the "text"
> binding is now provided by the first parameter, and (=<<) is used due to its
> similarity to fmap:
> bar :: Monad m => m String -> m String
> bar as = (=<<)  (\a -> if null a then return "nothing" else return
> "something")  as
> This works fine, so bar ["Blah"] gives ["something"], and bar (Just "")
> gives ["nothing"].
> But, I can get the same effect using a Functor (replacing (=<<) with fmap):
> bar2 :: Functor f => f String -> f String
> bar2 as = fmap (\a -> if null a then "nothing" else "something") as
> Can anyone help me out of the swamp?

Suppose I had functions:

bar3 :: Functor f => String -> f Bool
bar4 :: Funcotr f => Bool -> f Integer

If the only thing I have is the functor constraint, to chain them
together I have to end up with something of type (Functor f => String
-> f (f Integer)).

If I had a Monad constraint on bar3 and bar4 I could flatten the
result type and get rid of the "double nesting" and end up with a
function of type (String -> f Integer).

So it's not about what a single function can do, but what tools I have
to compose the functions.


More information about the Haskell-Cafe mailing list