Skip to content

Commit fdd873c

Browse files
authored
Add recursive generic example (#77)
Adds example of deriving recursive types / types with type variables and a note on orphan instances
1 parent 0b812f1 commit fdd873c

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,26 @@ instance decodeJsonTeam :: DecodeJson Team where
341341
decodeJson = genericDecodeJson
342342
```
343343

344+
Here is another example of how to derive a generic instance of a type with a type variable. This type also happens to be recursive:
345+
```purs
346+
data Chain a
347+
= End a
348+
| Link a (Chain a)
349+
350+
derive instance genericChain :: Generic (Chain a) _
351+
352+
instance encodeJsonChain :: EncodeJson a => EncodeJson (Chain a) where
353+
encodeJson c = genericEncodeJson c
354+
355+
instance decodeJsonChain :: DecodeJson a => DecodeJson (Chain a) where
356+
decodeJson c = genericDecodeJson c
357+
```
358+
359+
Note the addition of instance dependencies for the type variable `a`.
360+
Also note that these instances for a recursive type cannot be written in point-free style, as that would likely cause a stack overflow during execution. Instead, we use the variables `c` to apply eta-expansion.
361+
362+
More information about how to derive generic instances can be found in this [24-days-of-purescript post](https://github.com/paf31/24-days-of-purescript-2016/blob/master/11.markdown#deriving-generic-instances).
363+
344364
### Solving Common Problems
345365

346366
#### Handling Multiple JSON Representations
@@ -440,7 +460,7 @@ decodeJsonBlogPost username json = do
440460

441461
While not an issue specific to `argonaut-codecs`, you may sometimes wish to write an `EncodeJson` or a `DecodeJson` instance for a data type you did not define -- for instance, the `PreciseDateTime` type from `purescript-precise-datetime`. This type has no instances because there are many ways you might wish to represent it in JSON.
442462

443-
If you want to use an application-specific encoding for this type then you will need to define a newtype wrapper for it and define instances for that new type instead.
463+
If you want to use an application-specific encoding for this type then you will need to define a newtype wrapper for it and define instances for that new type instead. You cannot simply write an instance for the original `PreciseDateTime` type as that would be creating an orphan instance.
444464

445465
```purs
446466
module App.Data.PreciseDateTime where

0 commit comments

Comments
 (0)