Recently, Simon posted this message which describes a problem
that is caused by the fact that Haskell demands type constraints
to be of the form C a where C is a class identifier and a is a type
variable.
This is not the first time that people have complained about a problem of
this sort.
Since Gofer only lives on in the name Hugs, I am changing from Gofer to
Hugs 1.3. Boy, it's like being thrown back into the stone age. When
compared
to the Gofer class system the Haskell class system is so restrictive and
inflexible. I won't bother you with my programs that break down in Haskell,
but here are some more convincing examples:
Monad transformers
ftp://nebula.systemsz.cs.yale.edu/pub/yale-fp/papers/modular-interpreters.ps
Z
Tk/Gofer
http://www.informatik.uni-ulm.de/pm/ftp/tkgofer.html
Using GTC the active VRML stuff can be made even nicer
http://www.cs.yale.edu/HTML/YALE/CS/HyPlans/hudak-dir/RBML/essencevrml.ps
Now what can we do to fix the Haskell type system? Here is my proposal:
Let's just switch to the Gofer type system. It is well documented
(http://www.cs.nott.ac.uk/Department/Staff/mpj/thesis.html) and there is
a reference implementation available. Moreover, GTC already deal with
multiple parameter typeclasses, a feature that Haskell users will start
asking for in the near future.
In his thesis Mark writes about
the differences between Hugs and Haskell "The two languages are indeed
very close, and many programs that are written with one system in mind
can be used with the other with little or no changes." I think what he
means
is "The two languages are indeed very close, and many programs that are
written with Haskell in mind can be used in Gofer with little or no
changes."
That is most Haskell programs will still work under Gofer, but not vice
versa.
Any objections?
Simon's message:
>
> This type error comes up such a lot that I'm copying this message
> to the Haskell mailing list.
>
> | The following program does not typecheck under ghc-2.01 unless you
> | uncomment the type signature for test. (ghc-0.29 seems to propagate
> | the equality attribute correctly, and doesn't require the annotation.)
> |
> | module Test (test) where
> | -- test :: Eq a => [[a]] -> [a] -> [[a]]
> | test l xs = [ys | ys <- l, ys == map id xs]
>
> The problem here is that there isn't a most general type for test; this
is a
> shortcoming in the language, not the implementation. Consider: map has
type
>
> map :: Monad m => (a->b) -> m a -> m b
>
> Now, you are taking equality over those ys's, that equality over things
> of type (m b). So the "right" type for test is:
>
> test :: (Monad m, Eq (m a)) => [m a] -> m a -> [m a]
>
> But alas, Haskell doesn't like the Eq (m a) constraint, so it complains
> of a type error.
>
> The solution is presumably to generalise the type system a bit, so that
we
> recover the principal-type property.
>
> But we want to do the *right* generalisation. I know Mark Jones is
thinking
> about this; others are welcome to do so too!
>
> Simon
>