Version 14 (modified by 21 months ago) (diff) | ,
---|

# GHC 8.4.x Migration Guide

This guide summarises the changes you may need to make to your code to migrate from GHC 8.2 to GHC 8.4. This guide complements the GHC 8.4.x release notes which should be consulted as well.

## Compiler changes

### Type variable order in GADT constructors

The order in which type variables are quantified in GADT constructor type signatures has changed. Before, if you had `MkT`

as below:

data T a where MkT :: forall b a. b -> T a

Then the type of `MkT`

would (counterintuitively) be `forall a b. b -> T a`

! Now, GHC quantifies the type variables in the order that the users writes them, so the type of `MkT`

is now `forall b a. b -> T a`

(this matters for `TypeApplications`

).

`TypeInType`

is pickier

Some code which previously typechecked in earlier versions of GHC without the use of the `TypeInType`

extension will now require it in 8.4. For example:

myError :: forall (r :: RuntimeRep) . forall (a :: TYPE r) . String -> a myError = error

In spirit, this function has always required the `TypeInType`

extension, since the type variable `r`

is also used as a kind variable in `forall (a :: TYPE r)`

. However, GHC mistakenly didn't require the explicit use of `TypeInType`

here in earlier versions. This has been rectified in 8.4, so now `myError`

will not typecheck without `TypeInType`

being explicitly enabled.

In addition, prior GHCs would permit this sort of GADT, where the GADT return type constrains a *kind* parameter, without the use of `TypeInType`

:

data G (a :: k) where GInt :: G Int

Similarly, this now requires `TypeInType`

in GHC 8.4.

`TemplateHaskell`

reification changes for GADTs

Before GHC 8.4, whether or not Template Haskell would reify a data type as a `GadtC`

(or `RecGadtC`

) was somewhat unpredictable, as it used heuristics to determine whether a data type was declared using GADT syntax or not. While this worked for most use cases, there were nevertheless some corner cases where a GADT would not be reified as a `GadtC`

, and conversely, a non-GADT would be reified as a `GadtC`

. For example:

GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help λ> :set -XTemplateHaskell -XExistentialQuantification -XGADTs λ> import Language.Haskell.TH λ> data Foo a where MkFoo :: Show a => Foo a λ> $(reify ''Foo >>= stringE . show) "TyConI (DataD [] Ghci4.Foo [KindedTV a_6989586621679027473 StarT] Nothing [ForallC [] [AppT (ConT GHC.Show.Show) (VarT a_6989586621679027473)] (NormalC Ghci4.MkFoo [])] [])" λ> data Bar a = (a ~ Int) => MkBar λ> $(reify ''Bar >>= stringE . show) "TyConI (DataD [] Ghci6.Bar [KindedTV a_6989586621679027637 StarT] Nothing [ForallC [KindedTV a_6989586621679027637 StarT] [AppT (AppT (ConT Data.Type.Equality.~) (VarT a_6989586621679027637)) (ConT GHC.Types.Int)] (GadtC [Ghci6.MkBar] [] (AppT (ConT Ghci6.Bar) (VarT a_6989586621679027637)))] [])"

Note that `Foo`

, a GADT, is *not* reified as a `GadtC`

, whereas `Bar`

, which is not a GADT, *is* reified as a `GadtC`

. In GHC 8.4, this bug has been fixed, so as a result, `Foo`

will be reified as a `GadtC`

, but `Bar`

will not be, as one would expect.

In accordance with the changes to GADT constructor type variable order (mentioned above), reified GADT constructors also now track the order in which users wrote type variables. Continuing the earlier example:

data T a where MkT :: forall b a. b -> T a

In earlier GHCs, reifying `MkT`

would have yielded a type headed by `ForallC [PlainTV a, PlainTV b]`

. Now, reifying `MkT`

will give a type headed by `ForallC [PlainTV b, PlainTV a]`

, as one would expect.

### Deriving for empty data types

As part of this proposal was implemented, GHC now derives instances for empty data types (with no constructors) much differently than it did before. Here are the highlights:

- There is now an
`EmptyDataDeriving`

pragma which allows deriving`Eq`

,`Ord`

,`Read`

,`Show`

instances for empty data types. (Previously, this could only be done via`StandaloneDeriving`

, but with`EmptyDataDeriving`

, one can use`deriving`

clauses to accomplish the same thing now.)

- Previously, the generated code for derived instances for empty data types was quite awful, involving lots of uses of
`error`

. What follows a list of what code GHC used to derive for empty data types, contrasted with what GHC now derives after this proposal was implemented (using a running example of`data Empty a`

, with no constructors):

- Derived
`Eq`

and`Ord`

instances would previously emit code that used`error`

:

instance Eq (Empty a) where (==) = error "Void ==" instance Ord (Empty a) where compare = error "Void compare"

Now, they emit code that uses maximally defined, lazier semantics:

instance Eq (Empty a) where _ == _ = True instance Ord (Empty a) where compare _ _ = EQ

- Derived
`Read`

instances would previous emit code that used`parens`

:

instance Read (Empty a) where readPrec = parens pfail

But

`parens`

forces parts of the parsed string that it doesn't need to. Now, the derived instance will not use`parens`

(that it, parsing`Empty`

will always fail, without reading *any* input):

instance Read (Empty a) where readPrec = pfail

- Derived
`Show`

instances would previously emit code that used`error`

:

instance Show (Empty a) where showsPrec = "Void showsPrec"

Now, they emit code that inspects the argument. That is, if the argument diverges, then showing it will also diverge:

instance Show (Empty a) where showsPrec _ x = case x of {}

- Derived
`Functor`

,`Foldable`

,`Traversable`

,`Generic`

,`Generic1`

,`Lift`

, and`Data`

instances previously emitted code that used`error`

:

instance Functor Empty where fmap = error "Void fmap" instance Foldable Empty where foldMap = error "Void foldMap" instance Traversable Empty where traverse = error "Void traverse" instance Generic (Empty a) where from = M1 (error "No generic representation for empty datatype Empty") to (M1 _) = error "No values for empty datatype Empty" -- Similarly for Generic1 instance Lift (Empty a) where lift _ = error "Can't lift value of empty datatype Empty" instance Data a => Data (Empty a) where gfoldl _ _ _ = error "Void gfoldl" toConstr _ = error "Void toConstr" ...

Now, derived

`Functor`

,`Traversable,`

Generic`,`

Generic1`,`Lift`

, and`Data`

instances emit code which inspects their arguments:

instance Functor Empty where fmap _ x = case x of {} instance Traversable Empty where traverse _ x = pure (case x of {}) instance Generic (Empty a) where from x = M1 (case x of {}) to (M1 x) = case x of {} -- Similarly for Generic1 instance Lift (Empty a) where lift x = pure (case x of {}) instance Data a => Data (Empty a) where gfoldl _ x = case x of {} toConstr x = case x of {} ...

Derived

`Foldable`

instances now are maximally lazy:

instance Foldable Empty where foldMap _ _ = mempty

## Library changes

`base-4.11.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

`Semigroup`

/`Monoid`

superclasses

`Semigroup`

becomes a superclass of `Monoid`

with this release, please consult prime:wiki:Libraries/Proposals/SemigroupMonoid#Writingcompatiblecode for more information on recommendations for writing backward & forward compatible code.

`Typeable`

The kind-monomorphic `Typeable[1-7]`

classes, which were deprecated in GHC 7.8, have been removed from `Data.Typeable`

. They can be replaced with the usual (kind-polymorphic) `Typeable`

class.

`template-haskell-2.13.0.0`

## Tool changes

## GHC API changes

### Index types for the hsSyn AST

As part of ImplementingTreesThatGrow the index type for the hsSyn AST has been changed.

We now have

data GhcPass (c :: Pass) data Pass = Parsed | Renamed | Typechecked deriving (Data)

and synonyms

type GhcPs = GhcPass 'Parsed -- Old 'RdrName' type param type GhcRn = GhcPass 'Renamed -- Old 'Name' type param type GhcTc = GhcPass 'Typechecked -- Old 'Id' type para, type GhcTcId = GhcTc -- Old 'TcId' type param

So in practical terms, code will have to change as

fooParsed :: HsDecl RdrName fooRenamed :: HsDecl Name fooTypechecked :: HsDecl Id

becomes

fooParsed :: HsDecl GhcPs fooRenamed :: HsDecl GhcRn fooTypechecked :: HsDecl GhcTc

The following code provides backward-compatible versions of the new synonyms

#if __GLASGOW_HASKELL__ <= 802 type GhcPs = RdrName type GhcRn = Name type GhcTc = Id #endif