You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Mar 25, 2021. It is now read-only.
Copy file name to clipboardExpand all lines: README.md
+68-4Lines changed: 68 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -13,10 +13,74 @@ This library requires version 0.10 of the PureScript compiler, or later.
13
13
bower install purescript-generics-rep
14
14
```
15
15
16
-
## Examples
16
+
## Introduction
17
17
18
-
You can find an example of how Generics-Rep are applied in [this tutorial](https://purescript-simple-json.readthedocs.io/en/latest/generics-rep.html) of the Simple-JSON docs.
18
+
PureScript's generics are supported by the `Data.Generic.Rep.Generic` type class:
19
19
20
-
## Documentation
20
+
```purescript
21
+
class Generic a rep | a -> rep where
22
+
from :: a -> rep
23
+
to :: rep -> a
24
+
```
25
+
26
+
There are three interesting things here:
27
+
28
+
- The `rep` type argument and associated functional dependency define a type function from user types (`a`) to their _representations_ (`rep`).
29
+
-`from` converts a regular value into the representation type.
30
+
-`to` converts a representation value back into a regular value.
31
+
32
+
This library provides standard representation types which can be used to represent any `data` types which can be expressed in PureScript code.
33
+
34
+
It is possible to write out `Generic` instances for our own types by hand, but doing so is very laborious. Instead, we can _derive_ instances by using the `derive` keyword:
35
+
36
+
```purescript
37
+
newtype Person = Person { name :: String, location :: String }
38
+
39
+
derive instance genericPerson :: Generic Person _
40
+
```
41
+
42
+
Note that the second type argument, which represents the representation type, is specified as a type wildcard. This is useful, because representation types can get quite large, so it is inconvenient to type them out by hand in deriving declarations.
43
+
44
+
### Show, Eq, Ord
45
+
46
+
The key insight regarding generics is this: if we can write a function which works with any of the standard representation types, then we implement the same function for any instance of `Generic`. We can even exploit type information in our implementation by using additional type classes to reflect the type information at runtime.
47
+
48
+
`purescript-generics-rep` provides helper functions for implementing common type classes from the Prelude:
49
+
50
+
-`genericShow` gives a default implementation of `show` from the `Show` class
51
+
-`genericEq` gives a default implementation of `eq` from the `Eq` class
52
+
-`genericCompare` gives a default implementation of `compare` from the `Ord` class
53
+
-`genericAppend` gives a default implementation of `append` from the `Semigroup` class
54
+
-`genericMempty` gives a default implementation of `mempty` from the `Monoid` class
55
+
56
+
Using these functions is as simple as dropping the generic implementation into your instances:
57
+
58
+
```purescript
59
+
instance showPerson :: Show Person where
60
+
show = genericShow
61
+
62
+
instance eqPerson :: Eq Person where
63
+
eq = genericEq
64
+
65
+
instance ordPerson :: Ord Person where
66
+
compare = genericCompare
67
+
68
+
instance semigroupPerson :: Semigroup Person where
69
+
append = genericAppend
70
+
```
71
+
72
+
### Performance Concerns
73
+
74
+
Generic deriving can be very convenient for code generation, but it comes with a performance penalty. Consider defining a `Show` instance using `genericShow` - instead of simply converting our data type directly to a `String`, we first convert it to the representation type, and then convert that representation into a `String`. Creating this intermediate structure comes with a cost.
75
+
76
+
Thankfully, the `generics-rep` approach means that we only need to perform a shallow copy of the data, up to the first data constructor or record, so in practice the performance cost is acceptable. In the case of [foreign-generic](https://github.com/paf31/purescript-foreign-generic), the benefits listed above usually outweight the performance cost, since we rarely need to parse or generate JSON in performance-critical sections of code in many applications.
77
+
78
+
## API Documentation
79
+
80
+
API documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-generics-rep).
81
+
82
+
## Related libraries
21
83
22
-
Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-generics-rep).
84
+
* The [documentation for the simple-json library](https://purescript-simple-json.readthedocs.io/en/latest/generics-rep.html) includes a tutorial for using this library.
85
+
* Generic deriving of codecs for `Foreign` values: [purescript-foreign-generic](https://github.com/paf31/purescript-foreign-generic)
86
+
* Generic deriving of codecs for purescript-argonaut: [purescript-argonaut-generic](https://github.com/purescript-contrib/purescript-argonaut-generic)
0 commit comments