Hi Dave,

| What I missed on the initial reading is that this solution
| essentially adds an argument to each function call.

Exactly right.  Haskell's overloading facility allows the
type checker to add an appropriate extra argument for you automatically in
certain cases, but this is really just a
notational convenience.  There's no reason why a programmer
shouldn't be free to write in the target language of this
translation if they prefer.  Or, at least, that's the theory.

However, this doesn't actually work in Haskell because the
implementations for type class dictionaries require datatypes
with polymorphic components.  Once upon a time, there were a
lot of people who thought that the expressiveness of constructor
classes came from the ability to abstract over type constructors.
But that's only half the story.  To see what I mean, take a look
at what a dictionary for the Haskell 98 Functor class looks like:

  newtype Functor f
    = MkFunctor { fmap :: forall a, b. (a -> b) -> f a -> f b }
                          ^^^^^^^^^^^^
Recent versions of Hugs and GHC already support this feature,
but it is not in Haskell 98, so the implementation of overloading
is a source to source transformation in either of the former,
but not in the latter.

So yes, you could use this technique to code up monad transformers
etc. in Hugs and GHC.  Or you can use the overloading mechanisms,
just as you would have done with Gofer (remember that Hugs and GHC
have multiple parameter classes too now!).  Thus you have a choice
between explicit and implicit parameterization.  The former is
more flexible, but also more awkward because it gives the
programmer more work to do.  The latter is notationally more
convenient, but more limited, and only really appropriate when
there is at most one sensible implementation for any given
instance.

All the best,
Mark


Reply via email to