[Haskell-cafe] Overriding a Prelude function?

Claus Reinke claus.reinke at talk21.com
Thu Apr 23 19:18:06 EDT 2009

>> Well, than, what would you expect from this:
>> let {f x = g x;
>>      g 0 = 0;
>>      g n = f (n-1)}
>> in show f
> Well, not show, because any show instance for functions breaks r.t.  But the
> interactive interpreter, if it is not subject to r.t., might show:
> let { f x = g x;
>      g 0 = 0;
>      g n = f (n-1) } in f

Actually, most of those reduction systems were strongly, but 
dynamically typed, so the original example would give something
like this (no reductions possible):
    let {f x = g x;
          g 0 = 0;
          g n = f (n-1)}
    in show f

And if you applied something like 'show' to something it can work
with (let's wrap it in a function to make things interesting),

    \x->show [1,2]

you might get, unsurprisingly (but watch your representation levels!)


As far as referential transparency is concerned, you'd need to keep
your reference levels straight, which can seem confusing if you can
only communicate via representations(*:-) The easy part is semantics
and inverse

    eval :: representation -> meaning
    reify :: meaning -> representation

Since several program representations can have the same meaning, 
the inverse is not usually a function, but a relation, so Haskell picks 
a partial implementation of 'reify', named 'show', applicable only to 
things that have a uniquely determined representation. And since
Haskell implementations can't display things by themselves, they
use 'show' to show at least some things.

Now for the tricky part: as we write down or implement a semantics,
we're using a secondary level of representation, so we have representations
of program representations and representations of program meanings
(we might say that the 'semantics of 3', '[| 3 |]',  is the number '3'). 

In other words, we have a representation of 'eval' that maps 
representations of representations to representations of meanings.

So when we write down a program, it is a program to us, but just a string
to be interpreted for the implementation. And the implementation can
give back a representation of the meaning to us, without ever passing
such representation to other parts of the program (no 'show' involved).

Concretely, we type in '(\x->\y->x+2) 1', and the implementation 
gives back '\y->3' without having to support any kind of reification 
operation in the program itself - no problem with referential 
transparency there.


(*:-) ".. The name of the song is called `Haddocks' Eyes'"
    "Oh, that's the name of the song, is it?" Alice said, trying to
    feel interested. "No, you don't understand," the Knight said,
    looking a little vexed. "That's what the name is called. The
    name really is `The Aged Aged Man.'"
    "Then I ought to have said `That's what the song is called'?"
    Alice corrected herself. "No, you oughtn't: that's quite another
    thing! The song is called `Ways And Means': but that is only
    what it's called, you know!"
    "Well, what is the song, then?" said Alice, who was by this
    time completely bewildered. "I was coming to that," the Knight
    said. "The song really is `A-sitting On A Gate'.."
    (Lewis Caroll, Through The Looking-Glass)

More information about the Haskell-Cafe mailing list