... | ... | @@ -55,9 +55,17 @@ The use of `(~)` now requires `TypeOperators` instead of `GADTs` or `TypeFamilie |
|
|
* If `(~)` is used but `TypeOperators` is not enabled, GHC will produce a `-Wtype-equality-requires-operators` warning. This warning can be fixed by enabling `TypeOperators`.
|
|
|
* If `(~)` is used but is not imported transitively via `Data.Type.Equality` or `Prelude`, GHC will produce a `-Wtype-equality-out-of-scope` warning. This warning can be fixed by either importing one of these modules or, in the case where a custom `Prelude` is being used, re-exporting `(~)` from the custom `Prelude`.
|
|
|
|
|
|
### Type inference changes for local bindings with simplifiable constraints
|
|
|
### Removal of derived constraints
|
|
|
|
|
|
GHC can sometimes infer more restrictive type signatures in situations where a local binding without a type signature requires simplifiable constraints.
|
|
|
When GHC's typechecker tries to solve constraints, it can generate new derived constraints. For example, if we have a class with a functional dependency `C a b | a -> b`, if we have evidence for the two constraints `C a b1`, `C a b2` we can derive the equality constraint `b1 ~ b2`. GHC used to represent these derived constraints in a special form, but now they are normal Wanted constraints.
|
|
|
|
|
|
This can impact many situations in ways that aren't always predictable. Usually, it will involve GHC requiring stronger constraints when functional dependencies, injective type families, simplifiable constraints, or superclasses are involved. The end result is
|
|
|
usually that GHC will require additional constraints to be provided in type signatures.
|
|
|
|
|
|
#### Inference for simplifiable constraints
|
|
|
|
|
|
GHC can now require additional constraints that are derived from simplification of (and
|
|
|
interaction between) constraints.
|
|
|
|
|
|
For example, the following program no longer typechecks in GHC 9.4:
|
|
|
|
... | ... | @@ -95,7 +103,32 @@ g = go |
|
|
go = f
|
|
|
```
|
|
|
|
|
|
### No generalization over type variables determined by functional dependencies
|
|
|
#### Constraints derived from superclasses
|
|
|
|
|
|
GHC is similarly more restrictive with the following program
|
|
|
|
|
|
```hs
|
|
|
type family F x
|
|
|
|
|
|
class C a b | b -> a
|
|
|
|
|
|
class C b b => D b
|
|
|
|
|
|
f :: (C () b, D b) => Maybe b
|
|
|
f = g
|
|
|
|
|
|
g :: (C a b) => Maybe b
|
|
|
g = Nothing
|
|
|
```
|
|
|
|
|
|
In this situation, when typechecking `f`, GHC will see that we can obtain evidence for `C b b` from `D b` because of the superclass on `D`. Thus we get both `C () b` and `C b b`, and because of the functional dependency on `C`, GHC will require `() ~ b`. As that constraint wasn't provided in the type signature, the program is rejected. To make this program compile with 9.4 or later, add that as an explicit constraint:
|
|
|
|
|
|
```hs
|
|
|
f :: (C () b, D b, b ~ ()) => Maybe b
|
|
|
f = g
|
|
|
```
|
|
|
|
|
|
#### No generalization over type variables determined by functional dependencies
|
|
|
|
|
|
A small change has been made to the way GHC infers types for definitions with no type signature: GHC will no longer generalize a function over a type variable determined by a functional dependency. For example:
|
|
|
|
... | ... | @@ -120,30 +153,7 @@ error: |
|
|
|
|
|
If you want to retain the old behavior, add a (backward-compatible) type signature to `f`, explicitly requesting this unusual quantification.
|
|
|
|
|
|
A similar situation arises in this program:
|
|
|
|
|
|
```hs
|
|
|
type family F x
|
|
|
|
|
|
class C a b | b -> a
|
|
|
|
|
|
class C (F b) b => D b
|
|
|
|
|
|
f :: (C () b, D b) => Maybe b
|
|
|
f = g
|
|
|
|
|
|
g :: (C a b) => Maybe b
|
|
|
g = Nothing
|
|
|
```
|
|
|
|
|
|
GHC 9.4 will fail to compile this program because since it will not infer `F b ~ ()`. To make this compile with 9.4 or later, add that as an explicit constraint:
|
|
|
|
|
|
```hs
|
|
|
f :: (C () b, D b, F b ~ ()) => Maybe b
|
|
|
f = g
|
|
|
```
|
|
|
|
|
|
### GHC rejects ambiguous situations when solving for injective type families
|
|
|
#### GHC rejects ambiguous situations when solving for injective type families
|
|
|
|
|
|
There were previously cases around functional dependencies and injective type families where the result of type inference would depend on the order of constraints, as written in a source file. These cases are fundamentally ambiguous. While GHC previously made an arbitrary decision, it now notices the ambiguity and rejects the program.
|
|
|
|
... | ... | @@ -190,6 +200,10 @@ foo :: VSucc n -> VSucc n -> VSucc n |
|
|
foo (VSucc @n1 _) (VSucc @n2 _) = VSucc @n1 V -- Or, `VSucc @n2 V`
|
|
|
```
|
|
|
|
|
|
#### Impact to typechecking plugins
|
|
|
|
|
|
The `tcPluginSolve` method of `TcPlugin` now takes one fewer argument (the argument corresponding to Derived constraints has been removed). The `newDerived` function has also been removed; use `newWanted` instead.
|
|
|
|
|
|
### `\cases` is parsed differently when `-XLambdaCase` is enabled
|
|
|
|
|
|
When `-XLambdaCase` is enabled, the sequence `\ cases` (whitespace optional) is now parsed as the herald of a multi-pattern lambda-case expression. Thus GHC will reject a program if you have this extension enabled try to use a lambda expression whose first argument is called `cases`. Doing any of the following will make GHC 9.4 accept the program:
|
... | ... | |