To my recent propaganda for the overlapping instances

Marcin 'Qrczak' Kowalczyk  <[EMAIL PROTECTED]> writes on 27 Feb 2000

>> module G (g)
>> where
>> g:: Eq a => (a -> Bool) -> [a] -> [Bool]
>> g           h              xs  =  map h xs

> Back to the topic of visible imports. Change this definition to:
>
> g:: Eq a => (a -> Bool) -> [a] -> [Bool]
> g h xs@(x:_) = (Just x == Just x) : map h xs
>
> I don't have the CVS version of GHC, but if I understand how 
> things work, it will compile and answer [True,False].


If we want the recent implementations to compile this as needed, we
have to write
  g :: (Eq a, Eq (Maybe a)) => (a -> Bool) -> [a] -> [Bool]
              ------------
  g h xs@(x:_) = (Just x == Just x) : map h xs

- "because this  g  uses  Eq (Maybe a)".
This program  g  differs greatly from the initial one.
And the result is all right  [False,False]
- as it follows from the project in the modules F,G,E.

With omitting  Eq (Maybe a),  some implementations even report an
error - when compiling  E.  Others could report it as well, but 
maybe, somehow forget.
The implementations also solve successfully
                       g :: Eq (Maybe a) => (a->Bool)-> [a]-> [Bool]
- this context is shorter.
What the experts say, is this latter approach sound in general?

Finally, I continue suggesting what I call *deduced context*.
Compiling 
          f :: <Context> => <texpr>
          f ... = ...
the compiler has to deduce from  `<Context> => <texpr>',
from the body of  f,  from the instances used in  f 
all the necessary contexts <Context'> and add them silently,
obtaining   f :: <Context''> => <texpr>
            f ... = the same ...
That is the compiler starts with the sort of "error correcting".


> The question remains whether to prohibit them even when the relevant
> instances are not visible.

Looks like the compiler has to care only of the visible (in scope) 
relevant instances. Why should it care for others?

> If not, 
(if care only of visible things - S.M.)

> one must be careful to either import enough instances or provide
> explicit type signatures in all relevant places 

Most natural style. Why not?

> - failure to do so will produce incorrect result without warning, 

No: the same result, but maybe, with greatly different cost.
But I agree - to some extent: slowing down, say, in 100 times may 
look almost as troublesome as the wrong result.

> unless compilers maintain some extra information about which 
> instances were used and produce errors later (hoping that it is 
> not too complex at all).
>
> Moreover, when imports are visible (or hypothetically checked later),
> contexts must be more detailed even in cases where it is not in fact
> needed. For example, when instance Eq (Maybe String) is visible, the
> following function will not compile:
>    f :: Eq a => a -> Bool
>    f x = Just x == Just x
> [..]

See the suggestion for the deduced context.
Or, maybe, write  f :: Eq (Maybe a) => a -> Bool

> [..] A habit of defining instances in the module containing
> either the class definition or the type definition reduces the
> possibility of conflict to some two modules which would have to be
> [..]

Happily, it is only a habit!
I wonder how could I develop my CA project if this was the language 
requirement. This should have most stuckkily stuck it.
Or, at least, it would require some serious support for the mutually
recursive modules.

------------
And I recall now of a very important role of overlapping instances 
in the business of the 
                       implicit type (domain) casting
- see  http://www.botik.ru/pub/local/Mechveliani/basAlgPropos/,
       Section {dcon} Domain conversion proposal

To allow to set a wise conversion between the domains, Haskell needs 
some more powerful and generalized treating of overlapping instances, 
and the ones that mostly refer to the instances of multiparametric 
classes 
(may cause more problems, I do not know ...).
In brief, is has to support the overlapping instances like for the 
class  Cast a b.  Defining its instances (together with certain 
compiler pragma) gives a nice tool for the user to set the implicit 
domain casting.
Such a casting is of great importance, at least, in computer algebra.
It is a pity that, due to the overlaps lack, my recent CA program is
not able to support this cast. 

It is remarkable that  Fergus Henderson <[EMAIL PROTECTED]>  writes on
25 Feb 2000
> For Mercury, what we have been planning to do is to disallow overlapping
> instance declarations, but to allow dynamic type class casts,
> which give you a somewhat similar kind of expressive power.
> [..]

------------------
Sergey Mechveliani
[EMAIL PROTECTED]









Reply via email to