| The solution to the problem is that Hugs refuses to print values of
| polymorphic type!

Not so.  With the default settings, Hugs refuses to print values of
polymorphic type in situations where the output might potentially
differ with different choices of that type.  So Hugs will happily
accept something like:

  Main> [\x y -> x, \u v -> v]
  [<<function>>,<<function>>]
  Main>

The type here is [a -> a -> a], but because the standard method for
showing a function doesn't depend on the types of the argument or
result (it always displays "<<function>>"), we can go ahead and "show"
the result.

| Could Hugs be a bit more clever here?

I don't know.  Would a reminder to read the user manual help? :-)
There one might rediscover the command line option -u, which turns
off Hugs use of "show", and substitutes a built-in printer instead.
You loose some functionality this way, but now all your examples
work as you would like, with or without a deriving clause.

| Good old Miranda distinguished
| between scripts and command-level expressions.

Hugs does too, in several ways.  For example, in a script, there is
no pressing need to "show" any value.

| So please, change
| Hug's behaviour which is certainly a miracle to beginners and maybe
| also to the experienced Haskell programmer.

I would really like to see a concrete description of what you would
like to happen in a system that uses "show" instead of any built-in
printer to display values and yet still avoids the problems that
you've described.  It is not at all clear to me whether you can do
any better than what we already have.  The effects that you are seeing
are part of the price you pay for having a more sophisticated, and
user guided mechanism for controlling output.  In another message you
suggested: "The point is that if the type involves a type variable
we can substitute an arbitrary dictionary because it is never used!"
But I'm afraid this is simply not correct.  Think again about an
example like show [] to see why.  I agree that the default
behavior is confusing for beginners ... perhaps -u should be the
default ... but that might also be confusing too for some people.

Let me also point out that while the -u option might help in this
particular situation, it doesn't address the fundamental in the
underlying system.  For example, [] == [] will also be rejected,
not because it can't show the resulting Boolean (it can!), but
because it needs to know what type of lists are being compared.
You and I can see that the lists are empty, and that empty lists
are always equal.  But the type system can't see that --- its goal
is to approximate: not 42, but an integer; not True, but a Bool;
not the empty list [], but a list.  And with only approximate
information to work with, the results that it gives are inevitably
going to be approximations also.

All the best,
Mark

Reply via email to