Malcolm.Wallace at cs.york.ac.uk
Tue Nov 21 08:02:42 EST 2006
Simon Peyton-Jones <simonpj at microsoft.com> wrote:
> I think this thread is discussing your proposal 2, ignoring 1.
Indeed. Proposal 1 was from John Meacham, and I have edited it further
to show how even simple lists lead to non-confluence. I had hoped that
by simplifying from lists to unique types (in proposal 2), that we could
regain confluence. But your example below shows that I have not yet
fully achieved that goal.
> Suppose you had
> (Eq a, Foo a b, Num b)
> If I start with (Eq a) I might choose Integer. But if I start with
> Num b, I might choose default b=Float. Suppose I have
> instance Fractional a => Foo a Float
> Now I simplify (Foo a Float) to get Fractional a, and now I should
> choose a=Float.
Ah, but here you have an MPTC: Foo a b. Currently, Haskell'98 has no
story at all for how defaulting would work over MPTCs. According to the
Report, the type variable 'a' is not defaultable, because it is not
directly constrained by a numeric class. OK, so if we change the
example slightly to satisfy that condition, does Haskell'98 say anything
( Fractional a, Foo a b, Num b )
Of course, it still falls foul of the rule that a variable 'v' can only
be constrained in the form (C v), but setting that aside also...
So if I have instances:
instance Foo Float Integer
instance Foo Double Int
then which are the "first" types for 'a' and 'b' from the list to
satisfy all the constraints? The possible choices are incomparable with
each other for "firstiness".
My proposal for defaulting MPTCs does not fix this. I had failed to
consider the case that defaulting one of the variables may cause an
instance to become available, which might immediately constrain the
other variable(s) further. The order in which you choose to default
variables might therefore give you different constraints on the other
One solution might be simply to disallow defaulting over MPTC. (I can't
immediately think of any useful applications.)
Another solution might be to say that defaulting will only occur *if* it
is confluent, i.e. the compiler should try all possible orderings in
which to default variables, and if they do not come up with the same
answer, then reject the program.
More information about the Haskell-prime