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 Oct 4, 2020. It is now read-only.
This type and implementation states that the function `foo` is a `Lens` from any record with at least a `foo` field of type `a` to any record with at least a `foo` field of type `b`.
83
80
81
+
So, what are the type synonyms? Some examples are:
82
+
83
+
```purescript
84
+
type Lens s t a b = forall f. (Functor f) => (a -> f b) -> s -> f t
85
+
type LensP s a = Lens s s a a
86
+
87
+
type Prism s t a b = forall f p. (Applicative f, Choice p) => p a (f b) -> p s (f t)
88
+
type PrismP s a = Prism s s a a
89
+
```
90
+
91
+
These might seem scary, especially `Prism`, but if you squint at them properly, they look very familiar.
92
+
93
+
Let's take `Lens`, for example, and instantiate `s = [a], t = [b]`.
94
+
95
+
Then we have some type: `forall f. (Functor f) => (a -> f b) -> [a] -> f [b]`.
96
+
97
+
Looks pretty close to `map` (from `Data.Array`).
98
+
In fact, if we instantiate the `Functor` with `Identity`,
99
+
we get the type isomorphic to `map`: `(a -> Identity b) -> [a] -> Identity [b]`.
100
+
101
+
With some simple unwrapping, we actually have the type of `map`.
102
+
103
+
What about `Prism`?
104
+
105
+
Let's instantiate the `Choice` to `(->)`:
106
+
`type Prism s t a b = forall f. (Applicative f) => (a -> f b) -> s -> f t`
107
+
This looks pretty close to `traverse`.
108
+
109
+
So, there's a bunch of similarities to the `Functor` hierarchy, and that's one of the points of this library.
110
+
What these types synonyms allow is the ability to use similar idioms that work in the `Functor` hierarchy on containers that are not polymorphic in one variable.
111
+
112
+
An example of this is if you have some type: `data Foo = Foo Number`.
113
+
There's no way to define a `Functor` instance for `Foo`,
114
+
so you cannot use `(<$>), (<*>), (>>=), (=>>), pure, extract` and friends.
115
+
But, it should be easy to see that it would be trivial to "map" over the `Number` contained within a `Foo`.
116
+
117
+
If you can define a lens for `Foo`, you can do just that
118
+
119
+
```purescript
120
+
module Foo where
121
+
122
+
import Optic.Core ((*~), LensP())
123
+
124
+
data Foo = Foo Number
125
+
126
+
_Foo :: LensP Foo Number -- forall f. (Functor f) => (Number -> f Number) -> Foo -> f Foo
127
+
_Foo f (Foo n) = Foo <$> f n
128
+
129
+
doubleFoo :: Foo -> Foo
130
+
doubleFoo = _Foo *~ 2
131
+
```
132
+
133
+
Now, this is not necessarily the least verbose option for such a trivial example,
134
+
but it is definitely one of the more general options.
135
+
We were able to reuse plain old functions.
136
+
If we have some deeply nested structure, it is much less verbose for that situation.
137
+
84
138
## Examples
85
139
86
140
N.B. `(..)` is `(<<<)` purely for aesthetic reasons.
0 commit comments