... | ... | @@ -2,12 +2,47 @@ |
|
|
|
|
|
# GHC 9.6.x Migration Guide
|
|
|
|
|
|
This guide summarises the changes you may need to make to your code to migrate from GHC 9.4 to GHC 9.6. This guide complements the GHC 9.6.x release notes which should be consulted as well.
|
|
|
This guide summarises the changes you may need to make to your code to migrate from GHC 9.6 to GHC 9.6. This guide complements the GHC 9.6.x release notes which should be consulted as well.
|
|
|
|
|
|
# Core Library Changes
|
|
|
---
|
|
|
|
|
|
# Compiler Changes
|
|
|
## Compiler changes
|
|
|
|
|
|
## Undecidable Superclasses
|
|
|
### Type-changing record updates involving type families
|
|
|
|
|
|
## Type checking record updates |
|
|
\ No newline at end of file |
|
|
Record updates for GADTs and other existential datatypes are now fully supported. A side-effect of this change is that GHC now rejects some record updates involving fields whose types contain type families (these record updates were previously erroneously accepted).
|
|
|
|
|
|
Example:
|
|
|
|
|
|
```hs
|
|
|
type family F a where
|
|
|
F Int = Char
|
|
|
F Float = Char
|
|
|
|
|
|
data T b = MkT { x :: [Int], y :: [F b] }
|
|
|
|
|
|
emptyT :: forall b. T b
|
|
|
emptyT = MkT [] []
|
|
|
|
|
|
bar :: T Int
|
|
|
bar = emptyT { x = [3] }
|
|
|
```
|
|
|
|
|
|
In this example, we can't infer the type of `emptyT` in `bar`: it could be `T Int`, but it could also be `T Float` because the type family `F` is not injective and `T Float ~ T Int`. Indeed, the following typechecks:
|
|
|
|
|
|
```hs
|
|
|
baz :: T Int
|
|
|
baz = case ( emptyT :: T Float ) of { MkT _ y -> MkT [3] y }
|
|
|
```
|
|
|
|
|
|
This means that the type of `emptyT` is ambiguous in the definition of `bar` above, and thus GHC rejects the record update:
|
|
|
|
|
|
```
|
|
|
Couldn't match type `F b0' with `Char'
|
|
|
Expected: [F Int]
|
|
|
Actual: [F b0]
|
|
|
NB: ‘F’ is a non-injective type family
|
|
|
The type variable ‘b0’ is ambiguous
|
|
|
```
|
|
|
|
|
|
To fix these issues, add a type signature to the expression that the record update is applied to (`emptyT` in the example above), or add an injectivity annotation to the type family in the case that the type family is in fact injective. |
|
|
\ No newline at end of file |