Changes between Initial Version and Version 2 of Ticket #2748


Ignore:
Timestamp:
Nov 27, 2008 12:04:23 PM (7 years ago)
Author:
simonpj
Comment:

This is a scarily complicated piece of code. I wonder if would look simpler with type functions?

Still I took a look. I can see this:

-- Line 147-ish
class Map a b u v | u -> a, v -> b, b u -> v, a v -> u where ...
instance Map a b (a':.u) (b':.v) 
      => Map a b (a:.a':.u) (b:.b':.v) where ...

-- Line 68-ish
instance
    (...
    ,Map (a:.a:.a:.v) vv ((a:.a:.a:.v):.(a:.a:.a:.v):.m) vmt
    ...)  where ...

    )
     => 
    Det' a ((a:.a:.a:.v):.(a:.a:.a:.v):.(a:.a:.a:.v):.m)

Consider this simpler version:

  class C a b | a->b
  instance C Int Bool
  f :: C Int x => ...

GHC rejects the type ignature for 'f' because 'x' must be Bool. It's the same in an instance declaration

  instance C Int x => ...

And that's what you have here. The fundep b u -> v in class Map together with the instance declaration says that in any constraint

   Map ... tb (ta:ta':tu) vmt

then vmt must be of form (tb:tb':tv). But in your example it isn't.

Changing the instance decl to

instance
    (...
    ,Map (a:.a:.a:.v) vv ((a:.a:.a:.v):.(a:.a:.a:.v):.m)
         (vv :. vmt1 :. vmt2)
    ...)  where ...

    )
     => 
    Det' a ((a:.a:.a:.v):.(a:.a:.a:.v):.(a:.a:.a:.v):.m)

and replacing vmt by (vv:.vmt1:.vmt2) in the code, makes the error go away.

In short, when you use a type variable like vmt in a type signature, GHC assumes you mean a type variable and checks that you do. This is presumably a bug in 6.8.

I've taken the opportunity to improve the error message to say which fundep is involved. I'll close the bug though.

Simon

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #2748

    • Property Status changed from new to closed
    • Property Difficulty changed from to Unknown
    • Property Version changed from 6.8.3 to 6.10.1
    • Property Resolution changed from to invalid
  • Ticket #2748 – Description

    initial v2  
    1919}}}
    2020
    21 It's uglier for me to read and write but ultimately better for the user because I've eliminated a category of errors.  If the compiler will let me, I try to abbreviate 'T (T (T x)))' to 't' in the instance head, but I'm not always able to because 't' is more general than 'T (T (T x)))'. I'm not entirely sure how that factors into things. To see what I'm talking about, compile the attached file and look for the error that says {{{Couldn't match expected type `vmt' against inferred type `vv :. (b' :. v)' `vmt' is a rigid type variable...}}}. It has something to do with functional dependencies. The fundep involved demands that 'vmt' be of the type 'x :. y :. z :. etc' but in this particular case it's so verbose I just call it 'vmt'. 6.8 lets me do that. 6.10 doesn't. Who's right?
     21It's uglier for me to read and write but ultimately better for the user because I've eliminated a category of errors.  If the compiler will let me, I try to abbreviate 'T (T (T x)))' to 't' in the instance head, but I'm not always able to because 't' is more general than 'T (T (T x)))'. I'm not entirely sure how that factors into things. To see what I'm talking about, compile the attached file and look for the error that says
     22{{{
     23Couldn't match expected type `vmt' against inferred type `vv :. (b' :. v)'
     24`vmt' is a rigid type variable...
     25}}}
     26It has something to do with functional dependencies. The fundep involved demands that 'vmt' be of the type 'x :. y :. z :. etc' but in this particular case it's so verbose I just call it 'vmt'. 6.8 lets me do that. 6.10 doesn't. Who's right?
    2227
    2328