Sergey writes:

> Maybe, there exists another possibility to print the values in the
> error message like for 
>                        take (-1) xs,   y % 0 
> 
> The implementors declare the "internal" 
>                          class ServiceShow where serviceShows :: ...
> invisible for the user, 
> make *everything* to be the instance of  ServiceShow,

The problem with this is that there is a performance penalty to be
paid for overloading a function in this way.  `take' is implemented as
a function of two arguments, as you would expect.  It is given a
number and a list; it has no idea what type the list has, nor does it
need to: it just picks elements off it and returns them.

But because it has no idea what type the list has, it has no idea how
to print the contents of that list.  Enter the class mechanism.  If we
have

class ServiceShow where serviceShows :: ...

mytake :: ServiceShow a => Int -> [a] -> [a]

then mytake is now implemented as a function of *three* arguments: the
number and the list, as before, but also a `dictionary' which looks
like this:

data ServiceShowDict a = ServiceShowDict { serviceShows :: ... }

mytake_implementation :: ServiceShowDict a -> Int -> [a] -> [a]

[it's no accident that class constraints `C a =>' are written the way
they are... they are really extra arguments `CDict a ->'.]

and wherever `serviceShows' is called, the code really looks like:

mytake_implementation d n (x:xs) = ...   (serviceShows d) x ...


In other words, if you implement the above proposal, every invocation
of take will be passed an extra argument, which will be only very
rarely used.  Perhaps this could be turned on with a debugging option,
but in general it would be a Very Bad Thing performance-wise.



HTH.

--KW 8-)


Reply via email to