[Haskell-beginners] Re: computation vs function

Ertugrul Soeylemez es at ertes.de
Thu Apr 23 18:56:50 EDT 2009

Daniel Carrera <daniel.carrera at theingots.org> wrote:

> > What I refer to as a 'computation' in the article is actually just a
> > value of type 'Monad m => m a'.  I have chosen that term, because
> > you can apply it to any monad I've seen.  As mentioned in section 5,
> > you can think of 'Just 3' as being a computation, which results in
> > 3.  But it's important that this is not a function, but just an
> > independent value.
> Thanks.
> I think the article would benefit from making the meaning of
> computation clearer. The word computation appears in the tutorial 51
> times before section 5. That means that when I tried to go back for a
> definition of computation I couldn't find one.
> The first place you use the word computation is in the preamble, but
> that's not a good place to define terms. The second time you use the
> word computation is in section 2 "Motivation". This might be a good
> place to define the term. The Motivation section already defines
> several terms (referentially transparent, purely functional, etc), so
> it seems like a good place to define computation as well.
> In section 2 we can't say "Monad => m a" or "Just 3" because the terms
> are not introduced yet. Perhaps you could say something like this:
> <idea>
> The word 'computation' here is not a technical term. I use it to refer
> to something that returns a value without taking in any
> parameters. For example (m a) is a computation that takes no
> parameters but returns a value of type 'a' whereas (a -> b) is a
> function that takes a parameter of type 'a' and returns a value of
> type 'b'. It is important that a computation is not a function, but an
> independent value.
> </idea>
> I think that adding that as the third paragraph in the Motivation
> section would be helpful. In addition, in the Preamble, when you use
> the word computation, I would add "(see next section)".

Yes, you're right about that and I'm going to restructure it a bit, when
I've got some time.  But I can't do much more than clarifying that the
term is just an intuition and that it shouldn't be confused with
functions, maybe writing a bit more about the difference between the

This is precisely the reason why I mentioned Brent's blog post [1].  He
hit the nail right on the head.  I think a monads tutorial is supposed
to be read twice.

> Question: Would it be reasonable to say that a computation is a
> wrapper?  I'm not sure, because I don't know if a computation always
> results in the *same* value (you know, side-effects). I know that
> "Just 3" always results in 3, but is that universal?

Don't confuse the concept of a computation with the concept of running
it.  A computation does not result at all, unless you have a notion of
running it.  That notion defines what it means for a computation to
"result".  An IO computation can give different results in each run, a
Maybe computation can't.  I'm giving a few examples to make this

* IO:  Running an IO computation is possible through running the
  program.  There is no safe notion of running a computation from
  Haskell.  This is intentional, as you can see in more detail in the

* Parser:  Running a Parser computation is possible through parsing a
  text.  The result is the outcome of that process.

* State s:  Running a 'State s'-computation means calling the underlying
  function, which implements the stateful computation, with an initial
  state value.

* Maybe and []:  Running a Maybe or list computation is extracting its
  value through support functions (fromJust, maybe, head, tail, etc.) or
  through pattern matching.

Replace "wrapper" by "container", then you have another intuition for
monadic values.  An IO container contains some value, which depends on
world state, the Maybe container contains some value or not, the list
container contains arbitrarily many values, the Parser container
contains the outcome of parsing something, etc.

All in all, a monad is a wrapper type, but it doesn't exactly wrap
values.  There is an interesting counter-example, the unit monad:

  data Unit a = Unit

Think of it as a Maybe monad, which is constrained to Nothing.  There is
no result of the computation, there is no value in the container, there
is no whatever in the burrito.  Nonetheless Unit is a perfectly valid
monad and here is its instance:

  instance Monad Unit where
    return  = const Unit
    _ >>= _ = Unit


nightmare = unsafePerformIO (getWrongWife >>= sex)

More information about the Beginners mailing list