# 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 right-hand 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`

.

### Kind generalization and `MonoLocalBinds`

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:8-35 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 outer-scoped 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

`base-4.10.0.0`

#### Recommendations for forward-compatibility

In order to future-proof 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) ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances else -- provide/emulate `Control.Monad.Fail` and `Data.Semigroups` API for pre-GHC8 build-depends: fail == 4.9.*, semigroups == 0.18.*

See wiki:Migration/8.0#base-4.9.0.0 for more details

#### Type-indexed `Typeable`

changes

- The
`Data.Typeable.Internal`

module has been removed entirely. Much of the`Typeable`

internals now live in the new`Type.Reflection`

module. `Data.Typeable.TypeRep`

is now a type synonym (so you may need`TypeSynonymInstances`

to create an instance for it, unless you switch it to use`Type.Reflection.SomeTypeRep`

)`mkFunTy`

,`mkAppTy`

,`mkTyConApp`

, and`have been removed. If you use these then you might instead consider looking at the new type-indexed interfaces found in`

`Type.Reflection`

.`mkTyCon3`

and`mkTyConApp`

are no longer exported by`Data.Typeable`

. They are instead exported by`Type.Reflection.Unsafe`

.`Data.Dynamic`

no longer re-exports all of`Data.Typeable`

(only the`Typeable`

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 using`TypeApplications`

:

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 poly-kinded. Here are the kind signatures of these types before `base-4.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.

`template-haskell-2.12.0.0`

- The
`DataD`

,`NewtypeD`

,`DataInstD`

, and`NewtypeInstD`

constructors now take a`[DerivCxtQ]`

instead of a`CxtQ`

to represent`deriving`

clauses (#10598). 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 of`DerivCxtQ`

). - Each deriving clause now allows an optional strategy keyword, so a new
`DerivClause`

data type was introduced that contains a`Maybe DerivStrategy`

in addition to the usual`Cxt`

.

- 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 additional`Maybe DerivStrategy`

argument, since deriving strategy keywords can also be used with standalone`deriving`

declarations. The`standaloneDerivD`

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, use`standaloneDerivWithStrategyD`

.

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