Skip to content
This repository was archived by the owner on Mar 25, 2021. It is now read-only.

Commit 0d42177

Browse files
authored
Merge pull request #31 from anttih/add-guide
Add guide
2 parents 3bd3379 + 0294627 commit 0d42177

File tree

1 file changed

+68
-4
lines changed

1 file changed

+68
-4
lines changed

README.md

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,74 @@ This library requires version 0.10 of the PureScript compiler, or later.
1313
bower install purescript-generics-rep
1414
```
1515

16-
## Examples
16+
## Introduction
1717

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:
1919

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
2183

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

Comments
 (0)