[Haskell-beginners] Here's why functions should return functions

Ertugrul Söylemez es at ertes.de
Mon Jul 30 06:38:40 CEST 2012


Jay Sulzberger <jays at panix.com> wrote:

> There is, in most sub-systems of mathematics, whether like recent type
> theory or not, a general function, let us call it mcf which in Scheme
> notation may be defined by executing
>
> (define mcf
>    (lambda (a)
>      (lambda (x) a)))
>
> Now in Haskell I know that one, perhaps the, parallel definition must
> result in a polymorphic function.

First let's ensure that we are talking about the same function.  I'm
reading "mcf" as "make constant function".  From what I read the Haskell
equivalent would be this function:

    const a _ = a

It may make it not fully polymorphic, but if you don't provide a type
signature, then the following fully polymorphic type will be inferred:

    const :: a -> b -> a


> What is this definition?

Well, this is the constant function, though with slightly unusual (but
sensible) semantics for Scheme.  Because Scheme syntax requires explicit
currying the name "make constant function" would also be sensible.  It
is because of the lack of side effects that we call the function simply
'const' in Haskell.  Otherwise most functions would be prefixed with
"make".


> What implicit constraints are on a?

None.


> Does "lazy vs eager" come in here?

Yes.  Even though you have written a curried version of 'const' there,
Scheme is still a strict language, which means that the result of the
inner lambda will depend on its argument 'x'.  This means:

    -- Haskell:
    const a ⊥ = a

    -- in other words:
    loop = loop  -- an infinite loop
    const a loop = a

    ; Scheme:
    ((mcf a) ⊥) = ⊥

    (define (loop) (loop))  ; an infinite loop
    ((mcf a) (loop)) = (loop)

This is the semantic difference.  To relate this to "lazy vs. eager"
it's important to understand how a nonstrict language like Haskell is
usually evaluated:  Lazy evaluation will defer the evaluation of the
inner lambda's argument (which is an unnamed '_' here) until it is
required.  Since it is never required it is never evaluated and the
unevaluated thunk is garbage-collected immediately, unless it is used
elsewhere.

A strict language like Scheme is usually evaluated eagerly.  This means
that the inner lambda is not entered, until the argument is fully
evaluated.


> Are there options to ghc which might modify how Haskell handles the
> definition?

There are optimization flags, which could change the performance of the
definition, but a proper Haskell compiler like GHC must ensure that
semantics are not changed.


> Of course, my questions are too many and I hope just for some
> indications of the first things a beginner should study.

No worries.  I'm happy to help. =)


Greets,
Ertugrul

-- 
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20120730/adf81b88/attachment.pgp>


More information about the Beginners mailing list