Skip to content

7.0.2 ignores a context which 7.0.1 picks up

GHC 7.0.2 rejects programs which 7.0.1 accepts.

A passed context is not used, and the compiler (expectedly) fails to deduce an instance. Patching the code so that it works again is not difficult. Some type annotations can do the trick. So this is not a critical issue but it is a bit surprising.

I have simplified my code as much as possible so that it still shows the error in 7.0.2 (okIn701). I have included two further simplifications which produce no error : okInBoth and okInBoth'. I see why okInBoth is more simple (it side steps a type function), but I do not see why okInBoth' would avoid the problem.

The code also compiles if we remove the instance declaration for class B. In that case the type of a in okIn701 can be infered, and the context for that type is provided.

I have seen the following comment by dimitris in ticket #4981 (closed), which seems related. "I know why GHC is not picking the given up: it has to do with the fact that we have not saturated all possible equalities before we look for instances, but luckily this is something Simon and I are planning to fix pretty soon." Ticket #4981 (closed) seems to be an issue with 7.0.1. Here we see an apparent regression with 7.0.2, so I thought I would bring it up in case it is an unexpected change in behavior.

The diagnosis of ticket #3018 (closed) may be applicable to the code here: we may be asking too much of the compiler. As an additional simplification attempt, I have added function fromTicket3018, but it compiles fine with 7.0.1 and 7.0.2.

Also if the instance for 'B' is restricted to '[a]' (we can then remove the UndecidableInstances extension), and the type 'a' is replaced by '[a]' in 'okIn701', then it compiles fine. Are instances that match everything applied more eagerly ? If so then this compilatin problem should be quite rare.

> {-# LANGUAGE TypeFamilies, FlexibleInstances, UndecidableInstances, FlexibleContexts #-}

> class A a
> class B a where b :: a -> ()
> instance A a => B [a] where b = undefined

> newtype Y a = Y (a -> ())

> okIn701 :: B [a] => Y [a]
> okIn701 = wrap $ const () . b

> okInBoth' :: B a => Y a
> okInBoth' = wrap $ b

> okInBoth :: B a => Y a
> okInBoth = Y $ const () . b

> class Wrapper a where
>     type Wrapped a
>     wrap :: Wrapped a -> a
> instance Wrapper (Y a) where
>   type Wrapped (Y a) = a -> ()
>   wrap = Y

> fromTicket3018 :: Eq [a] => a -> ()
> fromTicket3018 x = let {g :: Int -> Int; g = [x]==[x] `seq` id} in ()

> main = undefined
Trac metadata
Trac field Value
Version 7.0.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information