Sun, 27 Feb 2000 19:21:05 +0300 (MSK), S.D.Mechveliani <[EMAIL PROTECTED]> pisze:

> 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].

(GHC-4.06 even answers [True,True] if e has the explicit type signature
with only Eq a in its context. From what Jeffrey R. Lewis said, I assume
that it will no longer compile.)

Type signatures must contain more detailed contexts to make overlapping
instances work: they must not be ever reduced from Eq (Maybe a) to Eq a.
Prohibiting such reductions indeed helps, makes global analysis of
what calls what and maintaining additional to types information of
compiled functions unneeded.

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

If so, contexts grow, overloaded polymorphic recursion is not typeable,
programs that don't use overlapping instances are slower and bigger,
I'm not sure if it would be usable at all.

If not, one must be careful to either import enough instances or
provide explicit type signatures in all relevant places - failure to
do so will produce incorrect result without warning, 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
even if I am going to never call f with the type instantiated to
String. OK, allowing it and later disallowing f True would not have
sense, but I'm not sure if it would be harmless in practice. In the
case where the compiler checks the consistency of used instances
across imports, substitute for String a private type used in only
one module which nevertheless has an instance of Eq (Maybe The-type).

Currently there is a problem of the same instance defined in several
modules. 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
mutually recursive for the conflict to arose. Now, well, instance Eq
(Maybe Some-type) does not create conflicts with Eq and Maybe that
can't be solved by growing contexts, but still has a global impact
on the program making certain previously valid definitions invalid
(provided that the compiler checks the consistency of used instances
across imports). Maybe it is not so big problem, but makes me worried.

-- 
 __("<    Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/              GCS/M d- s+:-- a22 C+++$ UL++>++++$ P+++ L++>++++$ E-
  ^^                  W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK                  5? X- R tv-- b+>++ DI D- G+ e>++++ h! r--%>++ y-

Reply via email to