Opened 16 months ago

Closed 16 months ago

Last modified 16 months 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 Revisions:

Description

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 #-}

class
  (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 16 months ago by divip

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

comment:2 follow-up: Changed 16 months ago by simonpj

  • Resolution set to invalid
  • Status changed from new to closed

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!

Simon

comment:3 Changed 16 months 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 16 months ago by divip

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

Note: See TracTickets for help on using tickets.