Brent Yorgey byorgey at seas.upenn.edu
Thu Mar 24 16:41:05 CET 2011

```On Wed, Mar 23, 2011 at 04:17:57PM -0400, Mike Meyer wrote:
> I'm working my way through Real World haskell, and so far have found
> the experience quite pleasant (though the harder exercises seem to
> require things net yet covered).
>
> Among the comments in the IO chapter was a discussion of whether or
> not some monad was or was not a function, which got me thinking.
>
> Values in haskell aren't evaluated until they're needed. They're
> implemented as thunks, meaning they're roughly zeroadic functions that
> will return the value when called.
>
> The syntax of the language seems to make treating values as zeroadic
> functions that return the value in question a reasonable
> interpretation as a degenerate case:
>
> (+)     accepts two arguments and returns their sum.
> (+ 5)   accepts one argument and returns that plus 5.
> (3 + 5) accepts zero arguments and returns 8.

It makes sense as a degenerate case if you look at things this way...

> or (more pedantically):
>
> (+)     accepts one argument and returns a function that accepts one
>         argument and returns a zeroadic function that returns the
>         value of the sum of the two arguments.
> (+ 5)   accepts one argument and returns a zeroadic function that ...
> (3 + 5) a zeroadic function that returns 8

... but as you note, really all functions take *one* argument, so now
calling values "zero-argument" functions seems less like a degenerate
case and more just like a weird special case.

> So the question is - is there any advantage or harm in this way of
> looking at values?

However, I don't think it's really all that harmful, and may even give
you some good intuition for laziness.  In a strict language, if you
want a lazy value of type T you can replace it by a function () -> T
-- which is sort of like a "zero-adic" function since it does take an
argument, but that argument contains no information.

-Brent

```