|
|
[[_TOC_]]
|
|
|
|
|
|
# GHC 8.10.x Migration Guide
|
|
|
|
|
|
|
... | ... | @@ -10,87 +12,149 @@ This guide summarises the changes you may need to make to your code to migrate f |
|
|
### Implicit kind variable changes
|
|
|
|
|
|
|
|
|
GHC 8.10 implements [ proposal 24](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0024-no-kind-vars.rst), which means that GHC is much less likely to implicitly quantify kind variables than it used to be. Here are some examples of code which will no longer work with GHC 8.10:
|
|
|
GHC 8.10 implements [proposal 24](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0024-no-kind-vars.rst), which means that GHC is much less likely to implicitly quantify kind variables than it used to be. Here are some examples of code which will no longer work with GHC 8.10:
|
|
|
|
|
|
- Kind variables are no longer implicitly quantified when an explicit `forall` is used at the beginning of a function's type signature. For instance, the following will no longer work:
|
|
|
* Kind variables are no longer implicitly quantified when an explicit `forall` is used at the beginning of a function's type signature. For instance, the following will no longer work:
|
|
|
|
|
|
```
|
|
|
{-# LANGUAGE PolyKinds #-}{-# LANGUAGE ScopedTypeVariables #-}f:: forall (a :: k).Proxy a
|
|
|
f=Proxy
|
|
|
```
|
|
|
```hs
|
|
|
{-# LANGUAGE PolyKinds #-}
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
|
|
```wiki
|
|
|
error: Not in scope: type variable ‘k’
|
|
|
|
|
|
|
6 | f :: forall (a :: k). Proxy a
|
|
|
| ^
|
|
|
```
|
|
|
f :: forall (a :: k). Proxy a
|
|
|
f = Proxy
|
|
|
```
|
|
|
```
|
|
|
error: Not in scope: type variable ‘k’
|
|
|
|
|
|
|
6 | f :: forall (a :: k). Proxy a
|
|
|
| ^
|
|
|
```
|
|
|
|
|
|
>
|
|
|
> This is because `k` is implicitly quantified in the kind of `a`. Here are two potential ways to migrate this code:
|
|
|
This is because `k` is implicitly quantified in the kind of `a`. Here are two potential ways to migrate this code:
|
|
|
|
|
|
1. If you are using GHC 8.0 or later, you can simply quantify `k` explicitly:
|
|
|
1. If you are using GHC 8.0 or later, you can simply quantify `k` explicitly:
|
|
|
|
|
|
```
|
|
|
f:: forall k (a :: k).Proxy a
|
|
|
f=Proxy
|
|
|
```
|
|
|
```hs
|
|
|
f :: forall k (a :: k). Proxy a
|
|
|
f = Proxy
|
|
|
```
|
|
|
|
|
|
>
|
|
|
> Note that GHC 8.0, 8.2, and 8.4 require enabling the `TypeInType` extension in order to do this. On GHC 8.6 or later, however, explicitly quantifying kind variables simply requires the `PolyKinds` extension.
|
|
|
Note that GHC 8.0, 8.2, and 8.4 require enabling the `TypeInType` extension in order to do this. On GHC 8.6 or later, however, explicitly quantifying kind variables simply requires the `PolyKinds` extension.
|
|
|
|
|
|
1. If you need to support versions of GHC older than 8.0, you may find the following piece of `CPP` useful:
|
|
|
2. If you need to support versions of GHC older than 8.0, you may find the following piece of `CPP` useful:
|
|
|
|
|
|
```
|
|
|
#if __GLASGOW_HASKELL__ >=800# define KVS(kvs) kvs
|
|
|
#else# define KVS(kvs)#endif
|
|
|
```hs
|
|
|
#if __GLASGOW_HASKELL__ >= 800
|
|
|
# define KVS(kvs) kvs
|
|
|
#else
|
|
|
# define KVS(kvs)
|
|
|
#endif
|
|
|
|
|
|
f :: forall KVS(k) (a :: k). Proxy a
|
|
|
f = Proxy
|
|
|
```
|
|
|
|
|
|
f:: forall KVS(k)(a :: k).Proxy a
|
|
|
f=Proxy
|
|
|
```
|
|
|
* Kind variables are no longer implicitly quantified in data constructor declarations:
|
|
|
|
|
|
- Kind variables are no longer implicitly quantified in data constructor declarations:
|
|
|
```hs
|
|
|
data T a = T1 (S (a :: k) | forall (b::k). T2 (S b) -- no longer accepted
|
|
|
data T (a :: k) = T1 (S (a :: k) | forall (b::k). T2 (S b) -- still accepted
|
|
|
```
|
|
|
|
|
|
```
|
|
|
dataT a =T1(S(a :: k)| forall (b::k).T2(S b)-- no longer accepteddataT(a :: k)=T1(S(a :: k)| forall (b::k).T2(S b)-- still accepted
|
|
|
```
|
|
|
As the above examples show, code that breaks because of this change can generally be fixed by adding explicit kind signatures to the type variable binders of the data type itself.
|
|
|
|
|
|
* Implicitly quantified kind variables are no longer put in front of other variables:
|
|
|
|
|
|
```hs
|
|
|
f :: Proxy (a :: k) -> Proxy (b :: j)
|
|
|
```
|
|
|
```
|
|
|
ghci> :t +v f -- old order:
|
|
|
f :: forall k j (a :: k) (b :: j). Proxy a -> Proxy b
|
|
|
|
|
|
ghci> :t +v f -- new order:
|
|
|
f :: forall k (a :: k) j (b :: j). Proxy a -> Proxy b
|
|
|
```
|
|
|
|
|
|
This is a breaking change for users of `TypeApplications`. If you wish to restore the old order, then explicitly quantify the type variables of `f`.
|
|
|
|
|
|
>
|
|
|
> As the above examples show, code that breaks because of this change can generally be fixed by adding explicit kind signatures to the type variable binders of the data type itself.
|
|
|
* In type synonyms and type family equations, free variables on the right-hand side are no longer implicitly quantified unless used in an *outermost* kind annotation:
|
|
|
|
|
|
- Implicitly quantified kind variables are no longer put in front of other variables:
|
|
|
```hs
|
|
|
type T = Just (Nothing :: Maybe a) -- no longer accepted
|
|
|
type T = Just Nothing :: Maybe (Maybe a) -- still accepted
|
|
|
```
|
|
|
|
|
|
### GHC infers fewer dependent kinds
|
|
|
|
|
|
GHC 8.10 features improvements to its kind inference engine. One downside to this is that it is slightly more conservative about inferring dependent kinds than it used to be. For example, the following example will kind-check on old versions of GHC, but not with GHC 8.10:
|
|
|
|
|
|
```hs
|
|
|
{-# LANGUAGE DataKinds, GADTs, PolyKinds, ScopedTypeVariables #-}
|
|
|
module Foo where
|
|
|
|
|
|
import Data.Kind
|
|
|
|
|
|
data T a where
|
|
|
MkT1 :: T Int
|
|
|
MkT2 :: T Bool
|
|
|
|
|
|
data ST a :: T a -> Type where
|
|
|
SMkT1 :: ST Int MkT1
|
|
|
SMkT2 :: ST Bool MkT2
|
|
|
```
|
|
|
```
|
|
|
f::Proxy(a :: k)->Proxy(b :: j)
|
|
|
Foo.hs:11:20: error:
|
|
|
• Expected kind ‘T a’, but ‘MkT1’ has kind ‘T Int’
|
|
|
• In the second argument of ‘ST’, namely ‘MkT1’
|
|
|
In the type ‘ST Int MkT1’
|
|
|
In the definition of data constructor ‘SMkT1’
|
|
|
|
|
|
|
11 | SMkT1 :: ST Int MkT1
|
|
|
| ^^^^
|
|
|
```
|
|
|
|
|
|
```wiki
|
|
|
ghci> :t +v f -- old order:
|
|
|
f :: forall k j (a :: k) (b :: j). Proxy a -> Proxy b
|
|
|
To fix this issue, one must give `ST` a complete, user-specified kind signature (consult [the relevant users' guide section](https://downloads.haskell.org/~ghc/8.6.4/docs/html/users_guide/glasgow_exts.html#complete-user-supplied-kind-signatures-and-polymorphic-recursion) for a more detailed description on what this means). In other words, apply the following change:
|
|
|
|
|
|
ghci> :t +v f -- new order:
|
|
|
f :: forall k (a :: k) j (b :: j). Proxy a -> Proxy b
|
|
|
```diff
|
|
|
-data ST a :: T a -> Type where
|
|
|
+data ST (a :: Type) :: T a -> Type where
|
|
|
```
|
|
|
|
|
|
>
|
|
|
> This is a breaking change for users of `TypeApplications`. If you wish to restore the old order, then explicitly quantify the type variables:
|
|
|
### GHC is pickier about impredicative uses of constraints
|
|
|
|
|
|
- In type synonyms and type family equations, free variables on the right-hand side are no longer implicitly quantified unless used in an *outermost* kind annotation:
|
|
|
Now that issue #11514 has been fixed, GHC is more stringent about impredicative uses of constraints. For example, the following program would be accepted on older versions of GHC, but not with GHC 8.10 or later:
|
|
|
|
|
|
```hs
|
|
|
foo :: forall a. (Show a => a -> a) -> ()
|
|
|
foo = undefined
|
|
|
```
|
|
|
typeT=Just(Nothing::Maybe a)-- no longer acceptedtypeT=JustNothing::Maybe(Maybe a)-- still accepted
|
|
|
|
|
|
`foo` is impredicative since it attempts to instantiate `undefined` at type `(Show a => a -> a) -> ()`. This can be fixed by simply adding the necessary wildcard patterns, like so:
|
|
|
|
|
|
```hs
|
|
|
foo :: forall a. (Show a => a -> a) -> ()
|
|
|
foo _ = undefined
|
|
|
```
|
|
|
|
|
|
### New RecordWildCards warnings
|
|
|
|
|
|
|
|
|
GHC 8.10 introduces two new flags, `-Wunused-record-wildcards` and `-Wredundant-record-wildcards`, which are implied by `-Wall`. This means that certain programs that use `RecordWildCards` will trigger warnings that did not do so previously. For instance, the following program emits no warnings on old versions of GHC, but will warn with GHC 8.10:
|
|
|
|
|
|
```hs
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
{-# OPTIONS_GHC -Wall #-}
|
|
|
|
|
|
data P = P { x :: Int, y :: Int }
|
|
|
|
|
|
f1 :: P -> Int
|
|
|
f1 P{..} = 1 + 3
|
|
|
|
|
|
f2 :: P -> Int
|
|
|
f2 P{x,y,..} = x + y
|
|
|
```
|
|
|
{-# LANGUAGE NamedFieldPuns #-}{-# LANGUAGE RecordWildCards #-}{-# OPTIONS_GHC -Wall #-}dataP=P{ x ::Int, y ::Int}f1::P->Intf1P{..}=1+3f2::P->Intf2P{x,y,..}= x + y
|
|
|
```
|
|
|
|
|
|
```wiki
|
|
|
Foo.hs:8:6: warning: [-Wunused-record-wildcards]
|
|
|
No variables bound in the record wildcard match are used
|
|
|
Possible fix: omit the ‘..’
|
... | ... | |