To my reply
>> I join this suggestion.
>> ..
>> ad hoc polymorphism is still very desirable.
>> As they are the overlapping instances with ad hoc resolution - more
>> generic than allowed by recent Haskell compilers.
Michael Hobbs <[EMAIL PROTECTED]> writes
> When considering changes to a language, I think one needs to carefully
> measure the difference between convenience and necessity/correctness. I
> think everyone will agree that ad hoc polymorphism (aka overloading) is
> very _convenient_ but I don't think that everyone will agree that it is
> the _correct_ thing to do. I know a few OO purists who will insist that
> overloading is a Bad Thing. Their reasoning: If a function does similar
> things, but with different types, define the function in terms of a
> common base class. If two functions do radically different things, but
> happen to be named the same, you have a naming problem. One of the
> functions should change its name.
> ...
> Perhaps a "better" solution than ad hoc polymorphism would be to provide
> a more convenient namespace syntax.
> ...
Naming policy would not help.
For example, in the below example, the user of application program has to
set in one's module
let
det = det_generic -- choice: det_Gauss, det_interpolation ...
...
f m n = (det m) + (det n) ...
...
Normally, the user has *not* to remember and to think which name to
apply for one and the same operation.
Thus, engineers, scientists simply set `det(M)' - do not mention how it
is computed - but presume, that in each situation it is computed in
some appropriate way. The system has to get automatically to the more
or less efficient special case in the circumstances.
Here is the practice.
My program suffers from the matrix determinant being called with the
three different names.
There are known at least three different ways, with essentially
different cost, to compute the matrix determinant - each usable in the
proper circumstances:
det :: Num a => [[a]] -> a --(N)
Euclidean a => [[a]] -> a --(E)
FiniteField a => [[Polynomial a]] -> Polynomial a --(FFP)
--univariate
Everyone will agree, the name `det' should be the same.
Algorithmically, the preference is:
if (FFP) instance fits then apply interpolation method
else
if (E) fits then
apply Gauss-like method with remainder division
else
if (N) fits then apply expansion by row that uses only +,-,*
Further, Num is a superclass for Euclidean and for (FFP),
FiniteField a => Polynomial a is an instance of Euclidean.
The natural solution is
class Lin a where det :: [[a]] -> a
...
instance Num a => Lin a where det = det_generic
instance Euclidean a => Lin a where det = det_GaussLike
instance FiniteField a => Lin (Polynomial a) where
det = det_interpolate
Then, the compiler has naturally to understand that here it has the
instance inclusion FFP -- E -- N and choose the most special possible
instance in each program.
And the existing compilers refuse to do this - do i mistake?
Further, i meet the cases now and then when the contexts, like
(FFP),(E) overlap and no one include in another.
The preferences there have to be set ad hoc, for example, by,
declaring the order (?).
This is what i call ad hoc polymorphism.
To my mind, it relates closely to the initial polymorphism requirement
for a polymorphic function - or do you think there is a great
difference?
On the other hand, could someone explain shortly to me and to other
Haskell users, which fundamental language benefints Haskell may loose
whith this ad hoc -ing?
------------------
Sergey Mechveliani
[EMAIL PROTECTED]