... | ... | @@ -12,85 +12,95 @@ This guide summarises the changes you may need to make to your code to migrate f |
|
|
|
|
|
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.
|
|
|
|
|
|
>
|
|
|
> 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:
|
|
|
|
|
|
- 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
|
|
|
|
|
|
```
|
|
|
f::Proxy(a :: k)->Proxy(b :: j)
|
|
|
```
|
|
|
ghci> :t +v f -- new order:
|
|
|
f :: forall k (a :: k) j (b :: j). Proxy a -> Proxy b
|
|
|
```
|
|
|
|
|
|
```wiki
|
|
|
ghci> :t +v f -- old order:
|
|
|
f :: forall k j (a :: k) (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`.
|
|
|
|
|
|
ghci> :t +v f -- new order:
|
|
|
f :: forall k (a :: k) j (b :: j). Proxy a -> Proxy b
|
|
|
```
|
|
|
* 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:
|
|
|
|
|
|
>
|
|
|
> This is a breaking change for users of `TypeApplications`. If you wish to restore the old order, then explicitly quantify the type variables:
|
|
|
```hs
|
|
|
type T = Just (Nothing :: Maybe a) -- no longer accepted
|
|
|
type T = Just Nothing :: Maybe (Maybe a) -- still accepted
|
|
|
```
|
|
|
|
|
|
- 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:
|
|
|
### New RecordWildCards warnings
|
|
|
|
|
|
```
|
|
|
typeT=Just(Nothing::Maybe a)-- no longer acceptedtypeT=JustNothing::Maybe(Maybe a)-- still accepted
|
|
|
```
|
|
|
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:
|
|
|
|
|
|
### New RecordWildCards warnings
|
|
|
```hs
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
{-# OPTIONS_GHC -Wall #-}
|
|
|
|
|
|
data P = P { x :: Int, y :: Int }
|
|
|
|
|
|
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:
|
|
|
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 ‘..’
|
... | ... | @@ -106,7 +116,6 @@ Foo.hs:11:10: warning: [-Wredundant-record-wildcards] |
|
|
| ^^
|
|
|
```
|
|
|
|
|
|
|
|
|
To fix the warnings, simply remove the uses of `..`, as neither use is necessary.
|
|
|
|
|
|
---
|
... | ... | |