... | ... | @@ -16,7 +16,7 @@ This guide summarises the changes you may need to make to your code to migrate f |
|
|
Consider the following function and data type:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
data Foo = MkFoo1 Int | MkFoo2 !Void
|
|
|
|
|
|
f :: Foo -> Int
|
... | ... | @@ -31,7 +31,7 @@ f (MkFoo1 i) = i |
|
|
However, previous versions of GHC did not recognize this fact and flagged `f` as being non-exhaustive. As a workaround, one had to explicitly match on `MkFoo2` in `f`:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
f :: Foo -> Int
|
|
|
f (MkFoo1 i) = i
|
|
|
f (MkFoo2 _) = error "unreachable"
|
... | ... | @@ -56,7 +56,7 @@ As a result, some code which compiled without warnings on previous versions of G |
|
|
Starting in GHC 8.8, we now generalize the kinds in the types of local definitions (e.g., `let`- or `where`-bound functions). As a result, there are a handful of programs which will no longer compile. Here is one such example:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
type family LetGo :: k
|
|
|
|
|
|
foo :: Proxy (LetGo :: Type)
|
... | ... | @@ -76,7 +76,7 @@ This kind-checks on previous versions of GHC, since the return kind of `LetGo` ( |
|
|
To avoid this, one can use an explicit kind signature on `LetGo`, like so:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
sGo :: x -> Proxy (LetGo :: Type)
|
|
|
sGo _ = foo
|
|
|
```
|
... | ... | @@ -88,7 +88,7 @@ To avoid this, one can use an explicit kind signature on `LetGo`, like so: |
|
|
If you have a type class like this:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
class C a where
|
|
|
method :: a
|
|
|
```
|
... | ... | @@ -97,7 +97,7 @@ class C a where |
|
|
Then in previous versions of GHC, reifying `C` with Template Haskell would give you something like this:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
class C a where
|
|
|
method :: forall a. C a => a
|
|
|
```
|
... | ... | @@ -115,7 +115,7 @@ There may be code in the wild that previously depended on the assumption that re |
|
|
GHC 8.8 tightened up the implementation of its unused import warning algorithm to more closely match the specification in [wiki:Commentary/Compiler/UnusedImports](commentary/compiler/unused-imports), as GHC 8.0 inadvertently introduced a [regression](https://ghc.haskell.org/trac/ghc/ticket/13064) that caused it to stray from this specification. As a result, some programs which compile without warnings on GHC 8.0 through 8.6 will now produce warnings on GHC 8.8. A good example that illustrates this is this one:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
{-# OPTIONS_GHC -Wunused-imports #-}
|
|
|
module T13064 where
|
|
|
|
... | ... | @@ -142,7 +142,7 @@ To summarize the reasoning from [wiki:Commentary/Compiler/UnusedImports](comment |
|
|
If one wishes to keep this sort of compiling without any warnings on both GHC 8.8 and previous versions, there are two options. One is to make both imports catch-all:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
{-# OPTIONS_GHC -Wunused-imports #-}
|
|
|
module T13064 where
|
|
|
|
... | ... | @@ -157,7 +157,7 @@ foo = () <$ pure () |
|
|
Alternatively, one can use `pure` qualified to avoid GHC warning about it:
|
|
|
|
|
|
|
|
|
```
|
|
|
```hs
|
|
|
{-# OPTIONS_GHC -Wunused-imports #-}
|
|
|
module T13064 where
|
|
|
|
... | ... | @@ -207,43 +207,31 @@ Previous versions of GHC would permit code that should require certain language |
|
|
|
|
|
1. Previously, GHC would accept some uses of type synonyms which did not have all of their arguments supplied without requiring the `LiberalTypeSynonyms` extension. Starting with version 8.8, GHC is stricter about requiring the extension in these cases.
|
|
|
|
|
|
>
|
|
|
>
|
|
|
> For example, this code requires `LiberalTypeSynonyms` in GHC 8.8:
|
|
|
>
|
|
|
>
|
|
|
|
|
|
```
|
|
|
type Generic i o = forall x. i x -> o x
|
|
|
type Id x = x
|
|
|
For example, this code requires `LiberalTypeSynonyms` in GHC 8.8:
|
|
|
|
|
|
foo :: Generic Id Id
|
|
|
foo = undefined
|
|
|
```
|
|
|
```hs
|
|
|
type Generic i o = forall x. i x -> o x
|
|
|
type Id x = x
|
|
|
|
|
|
>
|
|
|
>
|
|
|
> If GHC is complaining about type synonyms not being passed enough arguments or an 'illegal polymorphic type', try enabling `LiberalTypeSynonyms` in that module.
|
|
|
>
|
|
|
>
|
|
|
foo :: Generic Id Id
|
|
|
foo = undefined
|
|
|
```
|
|
|
|
|
|
If GHC is complaining about type synonyms not being passed enough arguments or an 'illegal polymorphic type', try enabling `LiberalTypeSynonyms` in that module.
|
|
|
|
|
|
```
|
|
|
{-# LANGUAGE RankNTypes #-}
|
|
|
2. Previously, it was possible to sneak in impredicative types through clever use of type synonyms. For instance, this code used to compile even without the `ImpredicativeTypes` extension enabled!
|
|
|
|
|
|
type Foo x = forall a. a -> a
|
|
|
type Bar x = Int -> Foo x
|
|
|
```hs
|
|
|
{-# LANGUAGE RankNTypes #-}
|
|
|
|
|
|
f :: [Bar ()] -- Impredicative!
|
|
|
f = []
|
|
|
```
|
|
|
type Foo x = forall a. a -> a
|
|
|
type Bar x = Int -> Foo x
|
|
|
|
|
|
f :: [Bar ()] -- Impredicative!
|
|
|
f = []
|
|
|
```
|
|
|
|
|
|
>
|
|
|
>
|
|
|
> GHC will now properly reject this:
|
|
|
>
|
|
|
>
|
|
|
GHC will now properly reject this:
|
|
|
|
|
|
```
|
|
|
• Illegal polymorphic type: forall a. a -> a
|
... | ... | |