GHC 8.2.x Migration Guide
This guide summarises the changes you may need to make to your code to migrate from GHC 8.0 to GHC 8.2. This guide complements the GHC 8.2.x release notes which should be consulted as well.
Compiler changes
DefaultSignatures
is pickier
There a new validity check for default class method implementations using XDefaultSignatures
. In particular, if you have a class Foo
:
class Foo a where
bar :: C => a > b > b
and you add a default type signature for bar
, it must be of the form:
default bar :: C' => a > b > b
That is, the righthand sides of the type signatures must be the same, but the contexts C
and C'
are allowed to be different. That means that these default type signatures for bar
:
default bar :: C' => b > a > b
default bar :: C' => b > b > a
default bar :: C' => a > b > b > b
will all be rejected.
These will also be rejected:
default bar :: C' => a > Int > Int
default bar :: C' => a > TF b > TF b
(where TF
is a type family). But it's possible to rearrange these into equivalent forms that GHC accepts: just use type equalities!
default bar :: (C', b ~ Int) => a > b > b
default bar :: (C', b ~ TF c) => a > b > b
As shown in the TF
example, you might have to create new type variables (e.g., c
) to make the type equalities work out.
Associated type family instances are pickier
There is also a new validity check for associated type family instances. That is, if you have a class with an associated type family:
class C a b where
type T a x b
And you create and instance of C
:
instance C ty1 ty2 where ...
Then the associated T
instance must look exactly like:
type T ty1 v ty2 = ...
 'ty1' for 'a'
 'ty2' for 'b', and
 some type `v` for 'x'
As a concrete example, this code, which would have been allowed before GHC 8.2, is now disallowed:
class Foo a where
type Bar a
instance Foo (Either a b) where
type Bar (Either c d) = d > c
To fix this instance, simply use the same type variables in the Bar
instance as in the instance head:
instance Foo (Either a b) where
type Bar (Either a b) = b > a
Instances for class synonyms are now disallowed
Previously, GHC silently accepted nonsense instance declarations like this:
type ReadShow a = (Read a, Show a)
instance Read Foo
instance Show Foo
instance ReadShow Foo
It's not even clear what this is supposed to mean, since ReadShow
isn't a class in and of itself. To disallow this, GHC now prevents all instances of the form instance (...) => Syn (...)
, where Syn
is a type synonym.
This check is a bit conservative, as it bars you from writing this as well:
type MyShow = Show
instance MyShow Foo
The workaround is to define the instance using Show
instead of MyShow
.
MonoLocalBinds
Kind generalization and The MonoLocalBinds
extension, which places limitations on when the type of a term is generalized, also affects when the kind of a type signature of generalized. Prior to GHC 8.2, there were certain scenarios when kinds signatures were incorrectly generalized in the presence of MonoLocalBinds
. This bug has now been fixed, but as a consequence, there are a handful of programs which will fail to typecheck without explicit kind signatures. Here is a known example:
{# LANGUAGE InstanceSigs #}
{# LANGUAGE MonoLocalBinds #}
{# LANGUAGE ScopedTypeVariables #}
{# LANGUAGE TypeInType #}
data Proxy a = Proxy
newtype Tagged s b = Tagged b
class C b where
c :: forall (s :: k). Tagged s b
instance C (Proxy a) where
c :: forall s. Tagged s (Proxy a)
c = Tagged Proxy
This compiles in GHC 8.0, but in GHC 8.2, it gives this error:
• Couldn't match type ‘k0’ with ‘k1’
because type variable ‘k1’ would escape its scope
This (rigid, skolem) type variable is bound by
the type signature for:
c :: forall k1 (s :: k1). Tagged s (Proxy a)
at Bug.hs:13:835
Expected type: Tagged s (Proxy a)
Actual type: Tagged s (Proxy a)
• When checking that instance signature for ‘c’
is more general than its signature in the class
Instance sig: forall (s :: k0). Tagged s (Proxy a)
Class sig: forall k1 (s :: k1). Tagged s (Proxy a)
In the instance declaration for ‘C (Proxy a)’
The reason for this error is that the type signature for c
captures a
, an outerscoped type variable, which means the type signature is not closed. Therefore, with MonoLocalBinds
enabled, the inferred kind for s
will not be generalized, and as a result, it will fail to unify with the kind variable k
which is specified in the declaration of c
.
This can be worked around by specifying an explicit kind variable for s
, e.g.,
instance C (Proxy a) where
c :: forall (s :: k). Tagged s (Proxy a)
c = Tagged Proxy
Library changes
base4.10.0.0
Recommendations for forwardcompatibility
In order to futureproof your packages for upcoming changes, add the following snippet to your .cabal
file, and address the warnings emitted by GHC when compiling your package:
if impl(ghc >= 8.0)
ghcoptions: Wcompat Wnoncanonicalmonadinstances Wnoncanonicalmonadfailinstances
else
 provide/emulate `Control.Monad.Fail` and `Data.Semigroups` API for preGHC8
builddepends: fail == 4.9.*, semigroups == 0.18.*
See wiki:Migration/8.0#base4.9.0.0 for more details
Typeable
changes
Typeindexed  The
Data.Typeable.Internal
module has been removed entirely. Much of theTypeable
internals now live in the newType.Reflection
module. 
Data.Typeable.TypeRep
is now a type synonym (so you may needTypeSynonymInstances
to create an instance for it, unless you switch it to useType.Reflection.SomeTypeRep
) 
mkFunTy
,mkAppTy
,mkTyConApp
, and `` have been removed. If you use these then you might instead consider looking at the new typeindexed interfaces found inType.Reflection
. 
mkTyCon3
andmkTyConApp
are no longer exported byData.Typeable
. They are instead exported byType.Reflection.Unsafe
. 
Data.Dynamic
no longer reexports all ofData.Typeable
(only theTypeable
class).
fromLabel
type signature change
The type signature of fromLabel
has changed:
fromLabel :: Proxy# x > a  old type signature
fromLabel :: a  new type signature
The new
fromLabel
can be accommodated usingTypeApplications
:
fromLabel (proxy# :: Proxy# "foo") :: alpha  old style
fromLabel @"foo" :: alpha  new style
GHC.Generics
is more polykinded
The Generic1
class, as well related classes and data types from GHC.Generics
, are now polykinded. Here are the kind signatures of these types before base4.10.0.0
:
class Generic1 (f :: * > *) where
type Rep1 f :: * > *
from1 :: f a > Rep1 f a
to1 :: Rep1 f a > f a
class Datatype (d :: k) where
datatypeName :: t d (f :: * > *) (a :: k1) > [Char]
moduleName :: t d (f :: * > *) (a :: k1) > [Char]
packageName :: t d (f :: * > *) (a :: k1) > [Char]
isNewtype :: t d (f :: * > *) (a :: k1) > Bool
class Constructor (c :: k) where
conName :: t c (f :: * > *) (a :: k1) > [Char]
conFixity :: t c (f :: * > *) (a :: k1) > Fixity
conIsRecord :: t c (f :: * > *) (a :: k1) > Bool
class Selector (s :: k) where
selName :: t s (f :: * > *) (a :: k1) > [Char]
selSourceUnpackedness :: t s (f :: * > *) (a :: k1) > SourceUnpackedness
selSourceStrictness :: t s (f :: * > *) (a :: k1) > SourceStrictness
selDecidedStrictness :: t s (f :: * > *) (a :: k1) > DecidedStrictness
data V1 (p :: *)
data U1 (p :: *) = U1
newtype Par1 p = Par1 p
newtype Rec1 (f :: * > *) (p :: *) = Rec1 (f p)
newtype K1 i c (p :: *) = K1 c
newtype M1 i c (f :: * > *) (p :: *) = M1 (f p)
data (:+:) (f :: * > *) (g :: * > *) (p :: *) = L1 (f p)  R1 (g p)
data (:*:) (f :: * > *) (g :: * > *) (p :: *) = f p :*: g p
newtype (:.:) (f :: * > *) (g :: * > *) (p :: *) = Comp1 (f (g p))
data family URec a (p :: *)
And here are their kind signatures now:
class Generic1 (f :: k > *) where
type Rep1 f :: k > *
from1 :: f a > Rep1 f a
to1 :: Rep1 f a > f a
class Datatype (d :: k) where
datatypeName :: t d (f :: k1 > *) (a :: k1) > [Char]
moduleName :: t d (f :: k1 > *) (a :: k1) > [Char]
packageName :: t d (f :: k1 > *) (a :: k1) > [Char]
isNewtype :: t d (f :: k1 > *) (a :: k1) > Bool
class Constructor (c :: k) where
conName :: t c (f :: k1 > *) (a :: k1) > [Char]
conFixity :: t c (f :: k1 > *) (a :: k1) > Fixity
conIsRecord :: t c (f :: k1 > *) (a :: k1) > Bool
class Selector (s :: k) where
selName :: t s (f :: k1 > *) (a :: k1) > [Char]
selSourceUnpackedness :: t s (f :: k1 > *) (a :: k1) > SourceUnpackedness
selSourceStrictness :: t s (f :: k1 > *) (a :: k1) > SourceStrictness
selDecidedStrictness :: t s (f :: k1 > *) (a :: k1) > DecidedStrictness
data V1 (p :: k)
data U1 (p :: k) = U1
newtype Par1 p = Par1 p
newtype Rec1 (f :: k > *) (p :: k) = Rec1 (f p)
newtype K1 i c (p :: k) = K1 c
newtype M1 i c (f :: k > *) (p :: k) = M1 (f p)
data (:+:) (f :: k > *) (g :: k > *) (p :: k) = L1 (f p)  R1 (g p)
data (:*:) (f :: k > *) (g :: k > *) (p :: k) = f p :*: g p
newtype (:.:) (f :: k2 > *) (g :: k1 > k2) (p :: k1) = Comp1 (f (g p))
data family URec a (p :: k)
It's possible that you might experience some typechecker errors due to this change. If so, a probable fix is to add explicit kind signatures in the right places.
templatehaskell2.12.0.0

The
DataD
,NewtypeD
,DataInstD
, andNewtypeInstD
constructors now take a[DerivCxtQ]
instead of aCxtQ
to representderiving
clauses (#10598 (closed)). This change was necessary because: Due to the introduction of deriving strategies, data types can now accept multiple deriving clauses (hence the need for
[DerivCxtQ]
instead ofDerivCxtQ
).  Each deriving clause now allows an optional strategy keyword, so a new
DerivClause
data type was introduced that contains aMaybe DerivStrategy
in addition to the usualCxt
.
 Due to the introduction of deriving strategies, data types can now accept multiple deriving clauses (hence the need for
Similarly, the
StandaloneDerivD
constructor now also takes an additionalMaybe DerivStrategy
argument, since deriving strategy keywords can also be used with standalonederiving
declarations. ThestandaloneDerivD
function's type signature remains unchanged, as it will produce a standalone deriving declaration with no strategy keyword. If you want to use an explicit keyword, usestandaloneDerivWithStrategyD
.
Tool changes
GHC API changes
 The
StaticFlags
module has been removed, as all static flags have been converted to dynamic ones in GHC 8.2.