... | ... | @@ -241,6 +241,67 @@ Previous versions of GHC would permit code that should require certain language |
|
|
In the type signature: f :: [Bar ()]
|
|
|
```
|
|
|
|
|
|
### Kind variable visibility in poly-kinded class methods
|
|
|
|
|
|
Previous versions of GHC were somewhat ambiguous about whether poly-kinded type class methods would make their kind variables be available for visible type application or not. This is best explained by examples. Consider the following two classes:
|
|
|
|
|
|
```haskell
|
|
|
class C1 (a :: k) b where
|
|
|
p1 :: Proxy a -> b
|
|
|
|
|
|
class C2 (a :: k) (b :: Type) where
|
|
|
p2 :: Proxy a -> b
|
|
|
```
|
|
|
|
|
|
On previous versions of GHC, the kind of `a` is *not* available for visible type application in `p1`, but it *is* available for visible type application in `p2`:
|
|
|
|
|
|
```
|
|
|
λ> :type +v p1
|
|
|
p1 :: forall {k} (a :: k) b. C1 a b => Proxy a -> b
|
|
|
λ> :type +v p2
|
|
|
p2 :: forall k (a :: k) b. C2 a b => Proxy a -> b
|
|
|
```
|
|
|
|
|
|
GHC 8.8 has cleaned up this infelicity, so now both `p1` and `p2` treat the kind of `a` as being available for visible type application:
|
|
|
|
|
|
```
|
|
|
λ> :type +v p1
|
|
|
p1 :: forall k (a :: k) b. C1 a b => Proxy a -> b
|
|
|
λ> :type +v p2
|
|
|
p2 :: forall k (a :: k) b. C2 a b => Proxy a -> b
|
|
|
```
|
|
|
|
|
|
There is a possibility that existing code will break due to this change. For example, the following code typechecks on old GHCs due to the aforementioned quirk of how GHC infers the kind of `a`:
|
|
|
|
|
|
```
|
|
|
class C (a :: k) b where
|
|
|
p :: Proxy a -> b
|
|
|
|
|
|
p' :: forall k (a :: k) b. C a b => Proxy a -> b
|
|
|
p' = p @a
|
|
|
```
|
|
|
|
|
|
This will no longer typecheck on GHC 8.8. There are two general approaches to migrating this code in a backwards-compatible fashion:
|
|
|
|
|
|
1. __Make `k` available for visible type application on all GHCs__. To do this, you can change the definition of `C` so that all type parameters have explicit kind signatures, like so:
|
|
|
|
|
|
```hs
|
|
|
class C (a :: k) (b :: Type) where
|
|
|
p :: Proxy a -> b
|
|
|
|
|
|
p' :: forall k (a :: k) b. C a b => Proxy a -> b
|
|
|
p' = p @k @a
|
|
|
```
|
|
|
2. __Make `k` unavailable for visible type application on all GHCs__. To do this, you can change the definition of `C` so that no type parameters have explicit kind signatures, like so:
|
|
|
|
|
|
```hs
|
|
|
class C a b where
|
|
|
p :: Proxy a -> b
|
|
|
|
|
|
p' :: forall k (a :: k) b. C a b => Proxy a -> b
|
|
|
p' = p @a
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
|
... | ... | |