Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#8994 closed bug (invalid)

type checker could not deduce ambiguous instances

Reported by: divip Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.8.2
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


GHC halts with a type error on the following program. If I comment out a seemingly unrelated part, it compiles though.

Tested with GHC 7.8.2

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}

  (F a ~ Int) =>  -- if this line is commented out, the program compiles
                 C a where
    type F a

    f :: b -> a

run :: (forall a. C a => a) -> ()
run _ = ()

x = run (f 0)  -- type error: Could not deduce (Num b0) arising from the literal ‘0’ from the context (C a)

Change History (4)

comment:1 Changed 3 years ago by divip

GHC 7.6.3 compiles is. GHC 7.8.1 does not compile it.

comment:2 Changed 3 years ago by simonpj

Resolution: invalid
Status: newclosed

The reason this works in 7.6.3 is because GHC defaults the ambiguous type variable 'b', which arises from the call to f in run (f 0). It sets b := Integer, and all is well.

But 7.8 is more cautious about defaulting. Consider:

class (c ~ Int) => C a c where
  type F a
  f :: b -> a

run :: (forall a c. C a c => a) -> ()

In this form there is another way to make the program typecheck, by setting b := c.

So GHC's defaulting rule (which is necessarily ad-hoc, and always was), is a bit more conservative in 7.8, and declines to set b := Integer in case you really intended b := c. So you need a type signature.

This would not be a hard design choice to liberalise. But I erred on the side of being conservative.

Generally speaking it's better not to rely on defaulting, anyway. Just use that type signature!

I'll close as invalid, but I'm open to user pressure!


comment:3 Changed 3 years ago by divip

Thanks for the explanation.

About my user experience: The example code was extracted from a bigger program. I did incremental refactoring steps on my program. In one step I introduced a new associated type which was independent of the rest of the program (like type F a above which should not interfere with defaulting), and my program stopped to compile. So I was almost sure this is a compiler bug.

Improving on this behaviour is not very important for me, it was just unexpected during programming.

comment:4 in reply to:  2 Changed 3 years ago by divip

Thanks, wrote a reply below before I noticed there is a reply button.

Note: See TracTickets for help on using tickets.