|
1 | | -# purescript-generics-rep |
| 1 | +# DEPRECATED |
2 | 2 |
|
3 | | -[](https://github.com/purescript/purescript-generics-rep/releases) |
4 | | -[](https://github.com/purescript/purescript-generics-rep/actions?query=workflow%3ACI+branch%3Amaster) |
5 | | -[](https://pursuit.purescript.org/packages/purescript-generics-rep) |
| 3 | +The library is no longer maintained under this repository as of the PureScript 0.14 compiler release. Relevant functionality has been moved into other repositories: |
6 | 4 |
|
7 | | -Generic programming using an approach inspired by GHC.Generics. |
| 5 | +- Most code has been moved to [`prelude`](https://github.com/purescript/purescript-prelude) |
| 6 | +- Enum-related code has been moved to [`enums`](https://github.com/purescript/purescript-enums) |
| 7 | +- The `Maybe` type's `Generic` instance has been moved to [`maybe`](https://github.com/purescript/purescript-maybe) |
| 8 | +- The `Either` type's `Generic` instance has been moved to [`either`](https://github.com/purescript/purescript-either) |
| 9 | +- The `Tuple` type's `Generic` instance has been moved to [`tuple`](https://github.com/purescript/purescript-either) |
8 | 10 |
|
9 | | -## Installation |
10 | | - |
11 | | -``` |
12 | | -spago install generics-rep |
13 | | -``` |
14 | | - |
15 | | -## Introduction |
16 | | - |
17 | | -PureScript's generics are supported by the `Data.Generic.Rep.Generic` type class: |
18 | | - |
19 | | -```purescript |
20 | | -class Generic a rep | a -> rep where |
21 | | - from :: a -> rep |
22 | | - to :: rep -> a |
23 | | -``` |
24 | | - |
25 | | -There are three interesting things here: |
26 | | - |
27 | | -- The `rep` type argument and associated functional dependency define a type function from user types (`a`) to their _representations_ (`rep`). |
28 | | -- `from` converts a regular value into the representation type. |
29 | | -- `to` converts a representation value back into a regular value. |
30 | | - |
31 | | -This library provides standard representation types which can be used to represent any `data` types which can be expressed in PureScript code. |
32 | | - |
33 | | -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: |
34 | | - |
35 | | -```purescript |
36 | | -newtype Person = Person { name :: String, location :: String } |
37 | | -
|
38 | | -derive instance genericPerson :: Generic Person _ |
39 | | -``` |
40 | | - |
41 | | -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. |
42 | | - |
43 | | -### Show, Eq, Ord |
44 | | - |
45 | | -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. |
46 | | - |
47 | | -`purescript-generics-rep` provides helper functions for implementing common type classes from the Prelude: |
48 | | - |
49 | | -- `genericShow` gives a default implementation of `show` from the `Show` class |
50 | | -- `genericEq` gives a default implementation of `eq` from the `Eq` class |
51 | | -- `genericCompare` gives a default implementation of `compare` from the `Ord` class |
52 | | -- `genericAppend` gives a default implementation of `append` from the `Semigroup` class |
53 | | -- `genericMempty` gives a default implementation of `mempty` from the `Monoid` class |
54 | | - |
55 | | -Using these functions is as simple as dropping the generic implementation into your instances: |
56 | | - |
57 | | -```purescript |
58 | | -instance showPerson :: Show Person where |
59 | | - show = genericShow |
60 | | -
|
61 | | -instance eqPerson :: Eq Person where |
62 | | - eq = genericEq |
63 | | -
|
64 | | -instance ordPerson :: Ord Person where |
65 | | - compare = genericCompare |
66 | | -
|
67 | | -instance semigroupPerson :: Semigroup Person where |
68 | | - append = genericAppend |
69 | | -``` |
70 | | - |
71 | | -### Performance Concerns |
72 | | - |
73 | | -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. |
74 | | - |
75 | | -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. |
76 | | - |
77 | | -## API Documentation |
78 | | - |
79 | | -API documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-generics-rep). |
80 | | - |
81 | | -## Related libraries |
82 | | - |
83 | | -- 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. |
84 | | -- Generic deriving of codecs for `Foreign` values: [purescript-foreign-generic](https://github.com/paf31/purescript-foreign-generic) |
85 | | -- Generic deriving of codecs for purescript-argonaut: [purescript-argonaut-generic](https://github.com/purescript-contrib/purescript-argonaut-generic) |
| 11 | +[Previous releases](https://github.com/purescript-deprecated/purescript-generics-rep/releases) will continue to work for older libraries which depend on them. |
0 commit comments