[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Two problems
To: Lennart Augustsson <augustss>
Cc: haskell@cs.glasgow.ac.uk, s.blott@cs.glasgow.ac.uk
Subject: Re: Two problems
Date: Tue, 29 Jan 91 09:03:45 +0000
From: Simon L Peyton Jones <simonpj@cs.glasgow.ac.uk>
Sender: haskell-request@cs.glasgow.ac.uk
| 1. It's not allowed to make an instance declaration in a module
| that does not contain the type and/or class declaration of the
| involved type and class. Why is this so? Why can't I define
| how pairs should be multiplied locally in a module?
| This restriction forces me to write
| type TPair a b = Pair a b
| instance (Num a) => Num (Pair a a) where
| (Pair a b) * (Pair c d) = Pair (a*c+a*d+b*c) (a*c+b*d)
| psnd (Pair x y) = y
| fib n = psnd ((Pair 1 0)^n)
|
| This problem was anticipated (and the restriction has in fact been
| removed in Haskell B).
There is a good reason for this: if the same type can have different
instances in different parts of the program, one loses principal types.
Steve Blott and Phil Wadler worked out the details of this, I think.
For example, suppose you defined multiplication on pairs in one
module in one way, and in another in another, and then imported both
modules into a third. How do pairs multiply now? Or are these instances
purely local to a module (seems a pity)? If so, how can instances
ever get exported?
It is not impossible that some design could retain principal types
while allowing local instances, but we thought things had got complicated
enough already!
| 2. My second problem came as a surprise and I don't know what the answer
| is. This is the real reason for this posting and I hope that the
| knowledgable Haskell commitee can give me the answer.
| The typing of "(1,0)" (I will use the builtin pairs for readablility) is
| "(1,0) :: (Num a, Num b)=>(a,b)". The instance declaration only says
| that "Num a => (a,a)" is an instance. Does this mean that the program has
| a type error or should the compiler conclude that the 0 and 1 must have
| the same type? The Haskell B compiler complains about a type error.
| The Glasgow Haskell compiler (version 0.402) does not complain, but the
| executable file it produces causes a core dump.
This actually shows up a bug in the report! It states that an
instance decl should have form
instance c => C (T u1 ... uk) where {d}
where u1...uk are type variables, BUT IT SHOULD SAY THAT THE TYPE
VARIABLES MUST BE DISTINCT. You can't say
instance Num a => Num (TPair a a) where ...
Why not? Because that purports to say when TPairs WITH COMPONENTS
OF THE SAME TYPE are in Num. So you might also want to say when
TPairs of different type are in Num
instance Num a, Num b => Num (TPair a b) where ...
Now the second instance includes the first, so what do we do?
There's lots of fun to be had here; for example, we could imagine
allowing nested constructors:
instance Num a => Num (TPair Int a) where ...
instance Num a => Num (TPair a Int) where ...
It is clearly getting hard to decide which instance applies. Again
maybe one could come up with a consistent design, but Haskell is
complicated enough already, and our brains became incapable of
figuring out all the ramifications. Well thought-through proposals
for Haskell 2 most welcome!
Meanwhile, to do what you want:
data TPair a = Pair a a
Now you can say
instance Num a => Num (TPair a) where ...
Simon