[Haskell-cafe] Re: Can we come out of a monad?

Ertugrul Soeylemez es at ertes.de
Wed Aug 11 09:17:03 EDT 2010

Thomas Davie <tom.davie at gmail.com> wrote:

> On 11 Aug 2010, at 12:39, Ertugrul Soeylemez wrote:
> > Martijn van Steenbergen <martijn at van.steenbergen.nl> wrote:
> >
> >> On 8/2/10 7:09, Ertugrul Soeylemez wrote:
> >>> Given the definition of a Haskell function, Haskell is a pure
> >>> language.  The notion of a function in other languages is not:
> >>>
> >>>   int randomNumber();
> >>>
> >>> The result of this function is an integer.  You can't replace the
> >>> function call by its result without changing the meaning of the
> >>> program.
> >>
> >> I'm not sure this is fair. It's perfectly okay to replace a call
> >> "randomNumber()" by that method's *body* (1), which is what you
> >> argue is okay in Haskell.
> >
> > This is not the same.  In Haskell you can replace the function call
> > by its /result/, not its body.  You can always do that.  But the
> > result of an IO-based random number generator is an IO computation,
> > not a value.  It's not source code either, and it's not a function
> > body.  It's a computation, something abstract without a particular
> > representation.
> It's still rather papering over the cracks to call this pure though.
> The IO based computation itself still has a result that you *can't*
> replace the IO based computation with.  The fact that it's evaluated
> by the runtime and not strictly in haskell may give us a warm fuzzy
> feeling inside, but it still means we have to watch out for a lot of
> things we don't normally have to in a "very pure"[1] computation.

You can always come up with the necessary transformations to replace a
function's call by its body.  But this is a trivial result and not
related to referential transparency.  It's like saying:  "You can
replace every while loop by a label and a goto".  What a discovery!

A while loop would be referentially transparent, if it had some notion
of a result and you could replace the entire loop by that.  And a
function is referentially transparent, if you can replace the function's
call or equivalently (!) the function's body by the function's result.

Referntially transparent functions are inherently memoizable.  A C
function is definitely not.

There is a fundamental difference between an IO computation's result and
a Haskell function's result.  The IO computation is simply a value, not
a function.  Its result is something abstract with no concrete
representation in Haskell.  In fact you can come up with mental models,
which make even those computations referentially transparent.  For
example this one:

  type IO = State RealWorld

You can only use (>>=) to give such a result a name, so you can refer to
it.  But this is not a function's result.  It's a value constructed in
some unspecified way and only accessible while running the program.

Remember:  Referential transparency is a property of source code!


nightmare = unsafePerformIO (getWrongWife >>= sex)

More information about the Haskell-Cafe mailing list