On 25/07/2011, at 2:12 AM, Alexander Shpilkin wrote:

> I've tried fixing #186 from the newbie list, which involves the
> following program:
> 
>> main () =
>>  do list = [1, 2, 3]
>>     println $ "list " % list % " : " $ show list
> 
> I fixed a problem in the defixer, and DDC now rejects this program with
> the following message:
> 
>> ./bug186.ds:3:38
>>        Kind mismatch during unification.
>>            cannot match: $ -> *
>>                    with: % -> *
>> 
>> ./bug186.ds:3:38
>>        Kind mismatch during unification.
>>            cannot match: $
>>                    with: %

Thanks! I've applied the patch.


> It may be "better" in the sense that it is not an internal error
> anymore, but -- is it right? I mean that I can't understand if this is
> the intended behaviour even after adding some tracing to
> DDC.Solve.State.Merge which is producing this error. Coming from
> Haskell, I'd expect some obvious type error here (a type mismatch in
> "list " % list ?).
> 
> Is this really the "right" error? If it is, is it possible to make it
> more understandable?

This is a correct error message, though I agree the explanation in the message 
could be improved.
 
Adding some parens to the offending line:

 println $ (("list " % list % " : ") $ show list)

The real problem here is that the second '$' wants a function as its first 
argument, but ("list " % list % " : ") is a String. A better error message 
would be "could not match type constructor String against type constructor 
(->)". It's complaining about "kind mismatch" because the String and (->) type 
constructor do have different kinds:

  String :: % -> *
  (->)   :: * -> * -> ! -> $ -> *

The reported mismatch is on the rightmost kind arrow, so (% -> *) does not 
match ($ -> *).

In DDC.Solve.Graph.Class we have:

        --   the primitive constraints that are contributing to the overall 
type of the class.
        | Class {
                -- | A unique id for this class
                  classId               :: !ClassId

                -- | The kind of the class.
                , classKind             :: !Kind        

...
                , classTypeSources      :: ![(Node, TypeSource)]         
        }


In the mergeClasses function of DDC.Solve.State.Merge, if we try to merge two 
classes with differing classKind fields, we get a kind error. However, if there 
are graph nodes containing type constructors (like String or (->)), or type 
applications in the classTypeSources list, then we could also report those. 
This would make the error messages easier to understand.

Adding the following line to mergeClasses_kindMismatch gives:
  liftIO $ putStrLn $ pprStrPlain $ map classTypeSources clss

$ bin/ddc -c test/14-Desugar/15-Defix/T186-OperatorSourcePosition/Main.ds
[[((289 290), TSV (SVInst 
./test/14-Desugar/15-Defix/T186-OperatorSourcePosition/Main.ds:8:41 ($)))], 
[(String, TSV (SVInst 
./test/14-Desugar/15-Defix/T186-OperatorSourcePosition/Main.ds:8:26 (%)))]]

That shows the String constructor. Unfortunately we can't directly see the (->) 
constructor because it's been applied to other types, eg (((((->) a1) a2) e1) 
c1). However, given the classId of a class contributing to a kind error, you 
could find the (->), or whatever by walking down the left spine of type 
applications. There are utils in DDC.Solve.Walk for this.
 
Cheers,
Ben.




-- 
Disciple-Cafe mailing list
http://groups.google.com/group/disciple-cafe

Reply via email to