Opened 7 years ago

Closed 4 years ago

#2544 closed bug (fixed)

Improve "Can't unify" error messages from type functions

Reported by: simonpj Owned by:
Priority: low Milestone: 7.0.2
Component: Compiler (Type checker) Version: 6.8.3
Keywords: Cc: jwlato@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: indexed-types/should_fail/T2544
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

Consider this example from a Haskell Cafe thread:

data (:|:) a b = Inl a | Inr b

class Ix i where
   type IxMap i :: * -> *
   empty  :: IxMap i [Int]

data BiApp a b c = BiApp (a c) (b c)

instance (Ix l, Ix r) => Ix (l :|: r) where
   type IxMap (l :|: r) = BiApp (IxMap l) (IxMap r)
   empty = BiApp empty empty

This elicits the following confusing error message:

     Couldn't match expected type `IxMap l'
            against inferred type `IxMap i'
       Expected type: IxMap (l :|: r) [Int]
       Inferred type: BiApp (IxMap i) (IxMap i1) [Int]
     In the expression: BiApp empty empty
     In the definition of `empty': empty = BiApp empty empty

As Alexander Dunlap responds, the error message is correct, but I can't help feeling that we should try harder to give a better error message. Something like "Since IxMap is a type function, knowing that IxMap l = IxMap i does not require that l = i". Or something.

This ticket is just to make sure we don't forget. The thread is here http://www.haskell.org/pipermail/haskell-cafe/2008-August/046371.html

Simon

Change History (7)

comment:1 Changed 7 years ago by simonmar

  • Architecture changed from Unknown to Unknown/Multiple

comment:2 Changed 7 years ago by simonmar

  • Operating System changed from Unknown to Unknown/Multiple

comment:3 Changed 5 years ago by igloo

  • Milestone changed from 6.12 branch to 6.12.3

comment:4 Changed 5 years ago by igloo

  • Milestone changed from 6.12.3 to 6.14.1
  • Priority changed from normal to low

comment:5 Changed 4 years ago by igloo

  • Milestone changed from 7.0.1 to 7.0.2

comment:6 Changed 4 years ago by jwlato

  • Cc jwlato@… added
  • Type of failure set to None/Unknown

With ghc-7.0.1, the error message is now:

bug.hs:11:12:
    Could not deduce (IxMap r ~ IxMap i1) from the context (Ix l, Ix r)
    NB: `IxMap' is a type function, and may not be injective
    Expected type: IxMap (l :|: r) [Int]
      Actual type: BiApp (IxMap l) (IxMap i1) [Int]
    In the expression: BiApp empty empty
    In an equation for `empty': empty = BiApp empty empty
    In the instance declaration for `Ix (l :|: r)'

bug.hs:11:18:
    Could not deduce (IxMap i ~ IxMap l) from the context (Ix l, Ix r)
    NB: `IxMap' is a type function, and may not be injective
    Expected type: IxMap l [Int]
      Actual type: IxMap i [Int]
    In the first argument of `BiApp', namely `empty'
    In the expression: BiApp empty empty
    In an equation for `empty': empty = BiApp empty empty
Failed, modules loaded: none.

Can this be closed? These error messages are much more useful (at least to my eye).

comment:7 Changed 4 years ago by simonpj

  • Resolution set to fixed
  • Status changed from new to closed
  • Test Case set to indexed-types/should_fail/T2544

It's even improved a bit more in HEAD

T2544.hs:15:12:
    Could not deduce (IxMap l ~ IxMap i0)
    from the context (Ix l, Ix r)
      bound by the instance declaration at T2544.hs:13:10-37
    NB: `IxMap' is a type function, and may not be injective
    Expected type: IxMap (l :|: r) [Int]
      Actual type: BiApp (IxMap i0) (IxMap r) [Int]
    In the return type of a call of `BiApp'
    In the expression: BiApp empty empty
    In an equation for `empty': empty = BiApp empty empty

T2544.hs:15:24:
    Could not deduce (IxMap i1 ~ IxMap r)
    from the context (Ix l, Ix r)
      bound by the instance declaration at T2544.hs:13:10-37
    NB: `IxMap' is a type function, and may not be injective
    Expected type: IxMap r [Int]
      Actual type: IxMap i1 [Int]
    In the second argument of `BiApp', namely `empty'
    In the expression: BiApp empty empty
    In an equation for `empty': empty = BiApp empty empty

So let's close. I'll add a test for completeness.

Thanks for bringing it up.

Simon

Note: See TracTickets for help on using tickets.