... | @@ -40,6 +40,46 @@ The old syntax which allowed quotes to be prefixed by `$` has been removed. |
... | @@ -40,6 +40,46 @@ The old syntax which allowed quotes to be prefixed by `$` has been removed. |
|
|
|
|
|
A new warning that needs to be enabled via `-fwarn-noncanonical-monad-instances` is available to help detect code which may be at risk.
|
|
A new warning that needs to be enabled via `-fwarn-noncanonical-monad-instances` is available to help detect code which may be at risk.
|
|
|
|
|
|
|
|
#### New `Generic` metadata representation
|
|
|
|
|
|
|
|
|
|
|
|
GHC 8.0 changes the way GHC generics encodes metadata. Previously, an empty data type would be generated for every datatype, constructor, and record selector associated with a `Generic` instance. For example:
|
|
|
|
|
|
|
|
```
|
|
|
|
dataExample a =Example a derivingGeneric
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
would have generated the following code prior to GHC 8.0:
|
|
|
|
|
|
|
|
```
|
|
|
|
instanceGeneric(Example a)wheretypeRep(Example a)=D1D1Example(C1C1_0Example(S1NoSelector(Rec0 a)))...dataD1ExampledataC1_0ExampleinstanceDatatypeD1Examplewhere...instanceConstructorC1_0Examplewhere...
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
GHC 8.0, on the other hand, does not generate empty data types. The `M1` data type in `GHC.Generics` has been modified so that it is parameterized by a new `Meta` type:
|
|
|
|
|
|
|
|
```
|
|
|
|
dataMeta=MetaDataSymbolSymbolSymbolBool|MetaConsSymbolFixityIBool|MetaSel(MaybeSymbol)SourceUnpackednessSourceStrictnessDecidedStrictnessnewtypeM1(i ::*)(c ::Meta)(f ::*->*)(p ::*)=M1{ unM1 :: f p }typeD1=M1DtypeC1=M1CtypeS1=M1S
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
There is now only one instance for `Datatype`, `Constructor`, and `Selector`. (For more information on how this works, see [ this](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Type-levelmetadataencoding).)
|
|
|
|
|
|
|
|
```
|
|
|
|
instanceDatatype('MetaData n m p nt)where...instanceConstructor('MetaCons n f r)where...instanceSelector('MetaSel mn su ss ds)where...
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
One major consequence of the additions to `MetaSel` is that the `NoSelector` datatype is insufficient to express all of the strictness properties of a record selector, so `NoSelector` was removed. If your generics-related code only mentions the `Datatype`, `Constructor`, and `Selector` typeclasses, it will not need to change. If your code does something more ambitious like checking for the presence of `NoSelector`, it will need to be updated to use `MetaSel` instead. For example, the above `Example` would have the following code generated:
|
|
|
|
|
|
|
|
```
|
|
|
|
instanceGeneric(Example a)wheretypeRep(Example a)=D1('MetaData"Example""Module""package"'False)(C1('MetaCons"Example"'PrefixI'False)(S1('MetaSel'Nothing'NoSourceUnpackedness'NoSourceStrictness'DecidedLazy)(Rec0 a)))
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Notice that since `Example` has no record selector, it generated `('MetaSel 'Nothing ...)` instead of `('MetaSel ('Just "recordName") ...)`.
|
|
|
|
|
|
#### …
|
|
#### …
|
|
|
|
|
|
TODO
|
|
TODO
|
... | | ... | |