Skip to content

Inferred context depends on whether instances are in scope

Consider the following program, I expect e1 and e2 to have contexts MyEq a and Eq a respectively.

{-# OPTIONS -fno-warn-redundant-constraints #-}

{-# LANGUAGE DatatypeContexts #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}

module T4966_Mod where

class MyEq w where
  meq :: w -> w -> Bool

-- A bizarre instance decl!
-- People who use instance decls like this are asking for trouble
instance {-# OVERLAPPABLE #-} GUIObject w => MyEq w where
  w1 `meq` w2 = toGUIObject w1 `meq` toGUIObject w2

instance {-# OVERLAPPABLE #-} GUIObject w => Eq w where
  w1 == w2 = toGUIObject w1 == toGUIObject w2

class GUIObject w where
  toGuiObject :: w -> Bool

e1 :: _ => a-> Bool
e1 state = state `meq` state

e2 :: _ => a-> Bool
e2 state = state == state

Compiling this program gives:

T4966_Mod.hs:24:7: error:
    • Found extra-constraints wildcard standing for ‘GUIObject a’
      Where: ‘a’ is a rigid type variable bound by
               the inferred type of e1 :: GUIObject a => a -> Bool
               at T4966_Mod.hs:24:1-19
      To use the inferred type, enable PartialTypeSignatures
    • In the type signature: e1 :: _ => a -> Bool

T4966_Mod.hs:27:7: error:
    • Found extra-constraints wildcard standing for ‘Eq a’
      Where: ‘a’ is a rigid type variable bound by
               the inferred type of e2 :: Eq a => a -> Bool
               at T4966_Mod.hs:27:1-19
      To use the inferred type, enable PartialTypeSignatures
    • In the type signature: e2 :: _ => a -> Bool

The context for e1 is simplified because there are no instances for MyEq in scope other than the instance defined in this module. The instance for e2 is not simplified because there are many instances for E2 in scope.

Related to #4966 (closed)

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information