Superclass inference (was: termination for FDs and ATs)

2006-05-05 Thread Simon Peyton-Jones
| Superclass implication is reversed when performing type inference.
| In the same way that instance reduction is reserved.
| 
| Here's the example again.
| 
|  class C a
|  class F a where
|type T a
|  instance F [a] where
|type T [a] = [[[a]]]
|  class C (T a) = D a
|  ^
| type function appears in superclass context
|  instance D [a] = C [[a]] -- satisfies Ross Paterson's Termination
Conditions
| 
| Consider
| 
|   D [a]
| --_superclassC (T [a]), D [a]
| --_type function C [[[a]]], D [a]
| --_instance  D [[a]], D [a]
| and so on
| 
| Of course, you'll argue that you apply some other inference methods.

Probably!  Let me explain what GHC does today, and see if that helps.
GHC tries to solve the following problem:

Input: a set of given constraints G
a set of wanted constraints W

Output: evidence that Y can be deduced from G+instance decls


During solving, GHC maintain two sets: the given set GG and the
wanted set WW. 

XX is maintained closed under superclasses; that is, when adding a
constraint (C t) to GG, I add all of C's superclasses.  GG is
initialised from G, closing under superclasses.

WW is initialised to W, but is *not* closed under superclasses.

Then we repeatedly pick a member of WW
a) if it's in GG, we are done
b) otherwise use an instance decl to simplify it, 
putting the new constraints back in WW
c) if neither applies, error.

In the pure inference case, the algorithm is slightly different:
Input: a set of wanted constraints W
Output: a minimal set of wanted constraints, G
  plus evidence for how to deduce W from G

GG starts empty.  The algorithm is the same as before, but in case (c)
we add the constraint to GG (plus its superclasses).  At the end,
extract G from GG; we want all the things that were not the
superclass-closure extras.


--

The point of explaining this is to say that in your example, (D [a]) is
part of Y, so GHC won't add D [a]'s superclasses in the first place, and
the problem you describe doesn't arise.  I don't know whether that is
luck, good judgement, or perhaps wrong.  

---

In the presence of ATs, I think that when adding a member to XX, or to
YY, we need to normalise the types wrt AT rewrites (a confluent
terminating process) first.  But that should do it.  (Of course, I have
proved nothing.)

Simon
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: termination for FDs and ATs

2006-05-05 Thread Ross Paterson
On Fri, May 05, 2006 at 08:42:12AM +0100, Simon Peyton-Jones wrote:
 Alas, g simply discards its argument, so there are no further
 constraints on 'a'.  I think Martin would argue that type inference
 should succeed with a=Bool, since there is exactly one solution.  Is
 this an example of what you mean?  

Actually a = Maybe Bool

 However, as a programmer I would not be in the least upset if inference
 failed, and I was required to add a type signature.  I don't expect type
 inference algorithms to guess, or to solve recursive equations, and
 that's what is happening here.

I think Martin is assuming the current Haskell algorithm: infer the type
of the function and then check that it's subsumed by the declared type,
while you're assuming a bidirectional algorithm.  That makes a big
difference in this case, but you still do subsumption elsewhere, so
Martin's requirement for normal forms will still be present.

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: termination for FDs and ATs

2006-05-05 Thread Martin Sulzmann
Ross Paterson writes:
  On Fri, May 05, 2006 at 08:42:12AM +0100, Simon Peyton-Jones wrote:
   Alas, g simply discards its argument, so there are no further
   constraints on 'a'.  I think Martin would argue that type inference
   should succeed with a=Bool, since there is exactly one solution.  Is
   this an example of what you mean?  
  
  Actually a = Maybe Bool
  
   However, as a programmer I would not be in the least upset if inference
   failed, and I was required to add a type signature.  I don't expect type
   inference algorithms to guess, or to solve recursive equations, and
   that's what is happening here.
  
  I think Martin is assuming the current Haskell algorithm: infer the type
  of the function and then check that it's subsumed by the declared type,
  while you're assuming a bidirectional algorithm.  That makes a big
  difference in this case, but you still do subsumption elsewhere, so
  Martin's requirement for normal forms will still be present.
  

A quick reply:

Subsumption among two type schemes boilds down to
testing whether (roughly)

Annotation_Constraint implies Infered_Constraint
  
given demanded

iff

Annotation_Constraint -  Annotation_Constraint /\ Infered_Constraint
 

So, of course the latter is more suitable for testing than the former.
(effectively, we push 'given' type information down the abstract syntax tree).
In any case, it's entirly unclear to me whether 'stopping' the 
AT inference process at some stage will guarantee complete
inference (in the presence of type annotations etc).

Martin




___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org//mailman/listinfo/haskell-prime