Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 505 lines (446 sloc) 20.821 kB
6be7786 @ekmett Factoring out Control.Lens.Type
authored
1 {-# LANGUAGE CPP #-}
2 {-# LANGUAGE GADTs #-}
3 {-# LANGUAGE Rank2Types #-}
4 {-# LANGUAGE FlexibleContexts #-}
5 {-# LANGUAGE FlexibleInstances #-}
6 {-# LANGUAGE ScopedTypeVariables #-}
7 {-# LANGUAGE MultiParamTypeClasses #-}
b54e109 @shachaf (f :: * -> *) in the definition of Equality
shachaf authored
8 {-# LANGUAGE KindSignatures #-}
6be7786 @ekmett Factoring out Control.Lens.Type
authored
9 -------------------------------------------------------------------------------
10 -- |
11 -- Module : Control.Lens.Type
12 -- Copyright : (C) 2012 Edward Kmett
13 -- License : BSD-style (see the file LICENSE)
14 -- Maintainer : Edward Kmett <ekmett@gmail.com>
15 -- Stability : provisional
16 -- Portability : Rank2Types
17 --
d7a3589 @ekmett more docs
authored
18 -- This module exports the majority of the types that need to appear in user
19 -- signatures or in documentation when talking about lenses. The remaining types
20 -- for consuming lenses are distributed across various modules in the hierarchy.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
21 -------------------------------------------------------------------------------
22 module Control.Lens.Type
23 (
a2cd8c1 @ekmett lots of new types
authored
24 -- * Other
25 Equality, Equality'
6be7786 @ekmett Factoring out Control.Lens.Type
authored
26 , Iso, Iso'
27 , Prism , Prism'
a2cd8c1 @ekmett lots of new types
authored
28 -- * Lenses, Folds and Traversals
29 , Lens, Lens'
30 , Traversal, Traversal'
6be7786 @ekmett Factoring out Control.Lens.Type
authored
31 , Setter, Setter'
a2cd8c1 @ekmett lots of new types
authored
32 , Getter, Fold
33 , Action, MonadicFold
34 -- * Indexed
35 , IndexedLens, IndexedLens'
36 , IndexedTraversal, IndexedTraversal'
37 , IndexedSetter, IndexedSetter'
38 , IndexedGetter, IndexedFold
39 , IndexedAction, IndexedMonadicFold
40 -- * Index-Preserving
41 , IndexPreservingLens, IndexPreservingLens'
42 , IndexPreservingTraversal, IndexPreservingTraversal'
43 , IndexPreservingSetter, IndexPreservingSetter'
44 , IndexPreservingGetter, IndexPreservingFold
45 , IndexPreservingAction, IndexPreservingMonadicFold
6be7786 @ekmett Factoring out Control.Lens.Type
authored
46 -- * Common
47 , Simple
48 , LensLike, LensLike'
49 , IndexedLensLike, IndexedLensLike'
50 , Overloading, Overloading'
6687426 @ekmett more equalities and docfixes
authored
51 , Overloaded, Overloaded'
6be7786 @ekmett Factoring out Control.Lens.Type
authored
52 ) where
53
54 import Control.Applicative
55 import Control.Lens.Internal
56 import Data.Profunctor
57
58 -- $setup
59 -- >>> import Control.Lens
60 -- >>> import Debug.SimpleReflect.Expr
61 -- >>> import Debug.SimpleReflect.Vars as Vars hiding (f,g,h)
62 -- >>> let f :: Expr -> Expr; f = Debug.SimpleReflect.Vars.f
63 -- >>> let g :: Expr -> Expr; g = Debug.SimpleReflect.Vars.g
64 -- >>> let h :: Expr -> Expr -> Expr; h = Debug.SimpleReflect.Vars.h
65 -- >>> let getter :: Expr -> Expr; getter = fun "getter"
66 -- >>> let setter :: Expr -> Expr -> Expr; setter = fun "setter"
5095463 @ekmett fixed prism test
authored
67 -- >>> import Numeric.Natural
e95b155 @ion1 Prism, Type: Apply the previous fix to the right place; remove $setup…
ion1 authored
68 -- >>> let nat :: Prism' Integer Natural; nat = prism toInteger $ \i -> if i < 0 then Left i else Right (fromInteger i)
6be7786 @ekmett Factoring out Control.Lens.Type
authored
69
70 -------------------------------------------------------------------------------
71 -- Lenses
72 -------------------------------------------------------------------------------
73
74 -- | A 'Lens' is actually a lens family as described in
75 -- <http://comonad.com/reader/2012/mirrored-lenses/>.
76 --
77 -- With great power comes great responsibility and a 'Lens' is subject to the
78 -- three common sense lens laws:
79 --
80 -- 1) You get back what you put in:
81 --
82 -- @'Control.Lens.Getter.view' l ('Control.Lens.Setter.set' l b a) ≡ b@
83 --
84 -- 2) Putting back what you got doesn't change anything:
85 --
86 -- @'Control.Lens.Setter.set' l ('Control.Lens.Getter.view' l a) a ≡ a@
87 --
88 -- 3) Setting twice is the same as setting once:
89 --
90 -- @'Control.Lens.Setter.set' l c ('Control.Lens.Setter.set' l b a) ≡ 'Control.Lens.Setter.set' l c a@
91 --
92 -- These laws are strong enough that the 4 type parameters of a 'Lens' cannot
93 -- vary fully independently. For more on how they interact, read the \"Why is
94 -- it a Lens Family?\" section of
95 -- <http://comonad.com/reader/2012/mirrored-lenses/>.
96 --
97 -- Every 'Lens' can be used directly as a 'Control.Lens.Setter.Setter' or
98 -- 'Traversal'.
99 --
100 -- You can also use a 'Lens' for 'Control.Lens.Getter.Getting' as if it were a
101 -- 'Fold' or 'Getter'.
102 --
40e0b6c @basdirks haddocks: formatting, punctuation and linking
basdirks authored
103 -- Since every 'Lens' is a valid 'Traversal', the
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
104 -- 'Traversal' laws are required of any 'Lens' you create:
6be7786 @ekmett Factoring out Control.Lens.Type
authored
105 --
106 -- @
107 -- l 'pure' ≡ 'pure'
108 -- 'fmap' (l f) '.' l g ≡ 'Data.Functor.Compose.getCompose' '.' l ('Data.Functor.Compose.Compose' '.' 'fmap' f '.' g)
109 -- @
110 --
111 -- @type 'Lens' s t a b = forall f. 'Functor' f => 'LensLike' f s t a b@
112 type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
113
114 -- | @type 'Lens'' = 'Simple' 'Lens'@
115 type Lens' s a = Lens s s a a
116
117 -- | Every 'IndexedLens' is a valid 'Lens' and a valid 'Control.Lens.Traversal.IndexedTraversal'.
118 type IndexedLens i s t a b = forall f p. (Indexable i p, Functor f) => p a (f b) -> s -> f t
119
120 -- | @type 'IndexedLens'' i = 'Simple' ('IndexedLens' i)@
121 type IndexedLens' i s a = IndexedLens i s s a a
122
d7a3589 @ekmett more docs
authored
123 -- | An 'IndexPreservingLens' leaves any index it is composed with alone.
f47d227 @ekmett Added cloneIndexPreservingLens, cloneIndexPreservingTraversal, cloneI…
authored
124 type IndexPreservingLens s t a b = forall p f. (SelfAdjoint p, Functor f) => p a (f b) -> p s (f t)
125
d7a3589 @ekmett more docs
authored
126 -- | @type 'IndexPreservingLens'' = 'Simple' 'IndexPreservingLens'@
f47d227 @ekmett Added cloneIndexPreservingLens, cloneIndexPreservingTraversal, cloneI…
authored
127 type IndexPreservingLens' s a = IndexPreservingLens s s a a
128
6be7786 @ekmett Factoring out Control.Lens.Type
authored
129 ------------------------------------------------------------------------------
130 -- Traversals
131 ------------------------------------------------------------------------------
132
133 -- | A 'Traversal' can be used directly as a 'Control.Lens.Setter.Setter' or a 'Fold' (but not as a 'Lens') and provides
134 -- the ability to both read and update multiple fields, subject to some relatively weak 'Traversal' laws.
135 --
136 -- These have also been known as multilenses, but they have the signature and spirit of
137 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
138 -- @'Data.Traversable.traverse' :: 'Data.Traversable.Traversable' f => 'Traversal' (f a) (f b) a b@
6be7786 @ekmett Factoring out Control.Lens.Type
authored
139 --
140 -- and the more evocative name suggests their application.
141 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
142 -- Most of the time the 'Traversal' you will want to use is just 'Data.Traversable.traverse', but you can also pass any
6be7786 @ekmett Factoring out Control.Lens.Type
authored
143 -- 'Lens' or 'Iso' as a 'Traversal', and composition of a 'Traversal' (or 'Lens' or 'Iso') with a 'Traversal' (or 'Lens' or 'Iso')
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
144 -- using ('.') forms a valid 'Traversal'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
145 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
146 -- The laws for a 'Traversal' @t@ follow from the laws for 'Data.Traversable.Traversable' as stated in \"The Essence of the Iterator Pattern\".
6be7786 @ekmett Factoring out Control.Lens.Type
authored
147 --
148 -- @
149 -- t 'pure' ≡ 'pure'
150 -- 'fmap' (t f) '.' t g ≡ 'Data.Functor.Compose.getCompose' '.' t ('Data.Functor.Compose.Compose' '.' 'fmap' f '.' g)
151 -- @
152 --
153 -- One consequence of this requirement is that a 'Traversal' needs to leave the same number of elements as a
154 -- candidate for subsequent 'Traversal' that it started with. Another testament to the strength of these laws
155 -- is that the caveat expressed in section 5.5 of the \"Essence of the Iterator Pattern\" about exotic
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
156 -- 'Data.Traversable.Traversable' instances that 'Data.Traversable.traverse' the same entry multiple times was actually already ruled out by the
6be7786 @ekmett Factoring out Control.Lens.Type
authored
157 -- second law in that same paper!
158 type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
159
160 -- | @type 'Traversal'' = 'Simple' 'Traversal'@
161 type Traversal' s a = Traversal s s a a
162
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
163 -- | Every IndexedTraversal is a valid 'Control.Lens.Traversal.Traversal' or
6be7786 @ekmett Factoring out Control.Lens.Type
authored
164 -- 'Control.Lens.Fold.IndexedFold'.
165 --
166 -- The 'Indexed' constraint is used to allow an 'IndexedTraversal' to be used
167 -- directly as a 'Control.Lens.Traversal.Traversal'.
168 --
169 -- The 'Control.Lens.Traversal.Traversal' laws are still required to hold.
f47d227 @ekmett Added cloneIndexPreservingLens, cloneIndexPreservingTraversal, cloneI…
authored
170 type IndexedTraversal i s t a b = forall p f. (Indexable i p, Applicative f) => p a (f b) -> s -> f t
6be7786 @ekmett Factoring out Control.Lens.Type
authored
171
172 -- | @type 'IndexedTraversal'' i = 'Simple' ('IndexedTraversal' i)@
173 type IndexedTraversal' i s a = IndexedTraversal i s s a a
174
d7a3589 @ekmett more docs
authored
175 -- | An 'IndexPreservingLens' leaves any index it is composed with alone.
f47d227 @ekmett Added cloneIndexPreservingLens, cloneIndexPreservingTraversal, cloneI…
authored
176 type IndexPreservingTraversal s t a b = forall p f. (SelfAdjoint p, Applicative f) => p a (f b) -> p s (f t)
177
d7a3589 @ekmett more docs
authored
178 -- | @type 'IndexPreservingTraversal'' = 'Simple' 'IndexPreservingTraversal'@
f47d227 @ekmett Added cloneIndexPreservingLens, cloneIndexPreservingTraversal, cloneI…
authored
179 type IndexPreservingTraversal' s a = IndexPreservingTraversal s s a a
180
6be7786 @ekmett Factoring out Control.Lens.Type
authored
181 ------------------------------------------------------------------------------
182 -- Setters
183 ------------------------------------------------------------------------------
184
185 -- |
186 -- The only 'Lens'-like law that can apply to a 'Setter' @l@ is that
187 --
f5f1b94 @basdirks haddocks: linking in Setter and Type
basdirks authored
188 -- @'Control.Lens.Setter.set' l y ('Control.Lens.Setter.set' l x a) ≡ 'Control.Lens.Setter.set' l y a@
6be7786 @ekmett Factoring out Control.Lens.Type
authored
189 --
f5f1b94 @basdirks haddocks: linking in Setter and Type
basdirks authored
190 -- You can't 'Control.Lens.Getter.view' a 'Setter' in general, so the other two laws are irrelevant.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
191 --
192 -- However, two 'Functor' laws apply to a 'Setter':
193 --
194 -- @
f5f1b94 @basdirks haddocks: linking in Setter and Type
basdirks authored
195 -- 'Control.Lens.Setter.over' l 'id' ≡ 'id'
196 -- 'Control.Lens.Setter.over' l f '.' 'Control.Lens.Setter.over' l g ≡ 'Control.Lens.Setter.over' l (f '.' g)
6be7786 @ekmett Factoring out Control.Lens.Type
authored
197 -- @
198 --
199 -- These an be stated more directly:
200 --
201 -- @
202 -- l 'pure' ≡ 'pure'
f5f1b94 @basdirks haddocks: linking in Setter and Type
basdirks authored
203 -- l f '.' 'untainted' '.' l g ≡ l (f '.' 'untainted' '.' g)
6be7786 @ekmett Factoring out Control.Lens.Type
authored
204 -- @
205 --
f5f1b94 @basdirks haddocks: linking in Setter and Type
basdirks authored
206 -- You can compose a 'Setter' with a 'Lens' or a 'Traversal' using ('.') from the @Prelude@
6be7786 @ekmett Factoring out Control.Lens.Type
authored
207 -- and the result is always only a 'Setter' and nothing more.
208 --
209 -- >>> over traverse f [a,b,c,d]
210 -- [f a,f b,f c,f d]
211 --
212 -- >>> over _1 f (a,b)
213 -- (f a,b)
214 --
215 -- >>> over (traverse._1) f [(a,b),(c,d)]
216 -- [(f a,b),(f c,d)]
217 --
218 -- >>> over both f (a,b)
219 -- (f a,f b)
220 --
221 -- >>> over (traverse.both) f [(a,b),(c,d)]
222 -- [(f a,f b),(f c,f d)]
223 type Setter s t a b = forall f. Settable f => (a -> f b) -> s -> f t
224
225 -- |
226 --
227 -- A 'Setter'' is just a 'Setter' that doesn't change the types.
228 --
229 -- These are particularly common when talking about monomorphic containers. /e.g./
230 --
231 -- @'sets' Data.Text.map :: 'Setter'' 'Data.Text.Internal.Text' 'Char'@
232 --
233 -- @type 'Setter'' = 'Setter''@
234 type Setter' s a = Setter s s a a
235
f5f1b94 @basdirks haddocks: linking in Setter and Type
basdirks authored
236 -- | Every 'IndexedSetter' is a valid 'Setter'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
237 --
238 -- The 'Setter' laws are still required to hold.
239 type IndexedSetter i s t a b = forall f p.
240 (Indexable i p, Settable f) => p a (f b) -> s -> f t
241
242 -- |
243 -- @type 'IndexedSetter'' i = 'Simple' ('IndexedSetter' i)@
244 type IndexedSetter' i s a = IndexedSetter i s s a a
245
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
246 -- | An 'IndexPreservingSetter' can be composed with a 'IndexedSetter', 'IndexedTraversal' or 'IndexedLens'
247 -- and leaves the index intact, yielding an 'IndexedSetter'.
2e40da2 @ekmett switched to self-adjoint in signatures
authored
248 type IndexPreservingSetter s t a b = forall p f. (SelfAdjoint p, Settable f) => p a (f b) -> p s (f t)
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
249
f47d227 @ekmett Added cloneIndexPreservingLens, cloneIndexPreservingTraversal, cloneI…
authored
250 type IndexPreservingSetter' s a = IndexPreservingSetter s s a a
251
6be7786 @ekmett Factoring out Control.Lens.Type
authored
252 -----------------------------------------------------------------------------
253 -- Isomorphisms
254 -----------------------------------------------------------------------------
255
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
256 -- | Isomorphism families can be composed with another 'Lens' using ('.') and 'id'.
5291c96 @ekmett Added notes about the index-preserving nature of Iso, Prism and Equal…
authored
257 --
a2cd8c1 @ekmett lots of new types
authored
258 -- Note: Composition with an 'Iso' is index- and measure- preserving.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
259 type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t)
260
261 -- |
262 -- @type 'Iso'' = 'Control.Lens.Type.Simple' 'Iso'@
263 type Iso' s a = Iso s s a a
264
265 ------------------------------------------------------------------------------
266 -- Prism Internals
267 ------------------------------------------------------------------------------
268
215d32b @basdirks haddocks cosmetics in Prism, Reified, Type
basdirks authored
269 -- | A 'Prism' @l@ is a 0-or-1 target 'Traversal' that can also be turned
270 -- around with 'Control.Lens.Review.remit' to obtain a 'Getter' in the
271 -- opposite direction.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
272 --
273 -- There are two laws that a 'Prism' should satisfy:
274 --
215d32b @basdirks haddocks cosmetics in Prism, Reified, Type
basdirks authored
275 -- First, if I 'Control.Lens.Review.remit' or 'Control.Lens.Prism.review' a value with a 'Prism' and then 'Control.Lens.Prism.preview' or use ('Control.Lens.Fold.^?'), I will get it back:
6be7786 @ekmett Factoring out Control.Lens.Type
authored
276 --
277 -- * @'Control.Lens.Prism.preview' l ('Control.Lens.Prism.review' l b) ≡ 'Just' b@
278 --
215d32b @basdirks haddocks cosmetics in Prism, Reified, Type
basdirks authored
279 -- Second, if you can extract a value @a@ using a 'Prism' @l@ from a value @s@, then the value @s@ is completely described my @l@ and @a@:
6be7786 @ekmett Factoring out Control.Lens.Type
authored
280 --
281 -- * If @'Control.Lens.Prism.preview' l s ≡ 'Just' a@ then @'Control.Lens.Prism.review' l a ≡ s@
282 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
283 -- These two laws imply that the 'Traversal' laws hold for every 'Prism' and that we 'Data.Traversable.traverse' at most 1 element:
6be7786 @ekmett Factoring out Control.Lens.Type
authored
284 --
285 -- @'Control.Lens.Fold.lengthOf' l x '<=' 1@
286 --
287 -- It may help to think of this as a 'Iso' that can be partial in one direction.
288 --
289 -- Every 'Prism' is a valid 'Traversal'.
290 --
291 -- Every 'Iso' is a valid 'Prism'.
292 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
293 -- For example, you might have a @'Prism'' 'Integer' 'Numeric.Natural.Natural'@ allows you to always
294 -- go from a 'Numeric.Natural.Natural' to an 'Integer', and provide you with tools to check if an 'Integer' is
295 -- a 'Numeric.Natural.Natural' and/or to edit one if it is.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
296 --
297 --
298 -- @
299 -- 'nat' :: 'Prism'' 'Integer' 'Numeric.Natural.Natural'
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
300 -- 'nat' = 'Control.Lens.Prism.prism' 'toInteger' '$' \\ i ->
6be7786 @ekmett Factoring out Control.Lens.Type
authored
301 -- if i '<' 0
302 -- then 'Left' i
303 -- else 'Right' ('fromInteger' i)
304 -- @
305 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
306 -- Now we can ask if an 'Integer' is a 'Numeric.Natural.Natural'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
307 --
308 -- >>> 5^?nat
309 -- Just 5
310 --
311 -- >>> (-5)^?nat
312 -- Nothing
313 --
314 -- We can update the ones that are:
315 --
316 -- >>> (-3,4) & both.nat *~ 2
317 -- (-3,8)
318 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
319 -- And we can then convert from a 'Numeric.Natural.Natural' to an 'Integer'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
320 --
321 -- >>> 5 ^. remit nat -- :: Natural
322 -- 5
323 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
324 -- Similarly we can use a 'Prism' to 'Data.Traversable.traverse' the left half of an 'Either':
6be7786 @ekmett Factoring out Control.Lens.Type
authored
325 --
326 -- >>> Left "hello" & _left %~ length
327 -- Left 5
328 --
329 -- or to construct an 'Either':
330 --
331 -- >>> 5^.remit _left
332 -- Left 5
333 --
334 -- such that if you query it with the 'Prism', you will get your original input back.
335 --
336 -- >>> 5^.remit _left ^? _left
337 -- Just 5
338 --
339 -- Another interesting way to think of a 'Prism' is as the categorical dual of a 'Lens'
215d32b @basdirks haddocks cosmetics in Prism, Reified, Type
basdirks authored
340 -- -- a /co/-'Lens', so to speak. This is what permits the construction of 'Control.Lens.Prism.outside'.
5291c96 @ekmett Added notes about the index-preserving nature of Iso, Prism and Equal…
authored
341 --
ffe3253 @ekmett s/Iso/Prism
authored
342 -- Note: Composition with a 'Prism' is index-preserving.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
343 type Prism s t a b = forall p f. (Prismatic p, Applicative f) => p a (f b) -> p s (f t)
344
215d32b @basdirks haddocks cosmetics in Prism, Reified, Type
basdirks authored
345 -- | A 'Simple' 'Prism'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
346 type Prism' s a = Prism s s a a
347
348 -------------------------------------------------------------------------------
3ce55f4 @ekmett Added 'Control.Lens.Equality'
authored
349 -- Equality
350 -------------------------------------------------------------------------------
351
a142679 @basdirks haddocks: more linking
basdirks authored
352 -- | A witness that @(a ~ s, b ~ t)@.
5291c96 @ekmett Added notes about the index-preserving nature of Iso, Prism and Equal…
authored
353 --
354 -- Note: Composition with an 'Equality' is index-preserving.
b54e109 @shachaf (f :: * -> *) in the definition of Equality
shachaf authored
355 type Equality s t a b = forall p (f :: * -> *). p a (f b) -> p s (f t)
3ce55f4 @ekmett Added 'Control.Lens.Equality'
authored
356
357 -- | A 'Simple' 'Equality'
358 type Equality' s a = Equality s s a a
359
360 -------------------------------------------------------------------------------
6be7786 @ekmett Factoring out Control.Lens.Type
authored
361 -- Getters
362 -------------------------------------------------------------------------------
363
364 -- | A 'Getter' describes how to retrieve a single value in a way that can be
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
365 -- composed with other 'Lens'-like constructions.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
366 --
367 -- Unlike a 'Lens' a 'Getter' is read-only. Since a 'Getter'
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
368 -- cannot be used to write back there are no 'Lens' laws that can be applied to
6be7786 @ekmett Factoring out Control.Lens.Type
authored
369 -- it. In fact, it is isomorphic to an arbitrary function from @(a -> s)@.
370 --
371 -- Moreover, a 'Getter' can be used directly as a 'Control.Lens.Fold.Fold',
372 -- since it just ignores the 'Applicative'.
373 type Getter s a = forall f. Gettable f => (a -> f a) -> s -> f s
374
70c7f3e @basdirks Getter.hs haddocks formatting, punctuation and linking.
basdirks authored
375 -- | Every 'IndexedGetter' is a valid 'Control.Lens.Fold.IndexedFold' and can be used for 'Control.Lens.Getter.Getting' like a 'Getter'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
376 type IndexedGetter i s a = forall p f. (Indexable i p, Gettable f) => p a (f a) -> s -> f s
377
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
378 -- | An 'IndexPreservingGetter' can be used as a 'Getter', but when composed with an 'IndexedTraversal',
379 -- 'IndexedFold', or 'IndexedLens' yields an 'IndexedFold', 'IndexedFold' or 'IndexedGetter' respectively.
2e40da2 @ekmett switched to self-adjoint in signatures
authored
380 type IndexPreservingGetter s a = forall p f. (SelfAdjoint p, Gettable f) => p a (f a) -> p s (f s)
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
381
6be7786 @ekmett Factoring out Control.Lens.Type
authored
382 --------------------------
383 -- Folds
384 --------------------------
385
386 -- | A 'Fold' describes how to retrieve multiple values in a way that can be composed
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
387 -- with other 'Lens'-like constructions.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
388 --
a142679 @basdirks haddocks: more linking
basdirks authored
389 -- A @'Fold' s a@ provides a structure with operations very similar to those of the 'Data.Foldable.Foldable'
390 -- typeclass, see 'Control.Lens.Fold.foldMapOf' and the other 'Fold' combinators.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
391 --
a142679 @basdirks haddocks: more linking
basdirks authored
392 -- By convention, if there exists a 'foo' method that expects a @'Data.Foldable.Foldable' (f a)@, then there should be a
6be7786 @ekmett Factoring out Control.Lens.Type
authored
393 -- @fooOf@ method that takes a @'Fold' s a@ and a value of type @s@.
394 --
a142679 @basdirks haddocks: more linking
basdirks authored
395 -- A 'Getter' is a legal 'Fold' that just ignores the supplied 'Data.Monoid.Monoid'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
396 --
397 -- Unlike a 'Control.Lens.Traversal.Traversal' a 'Fold' is read-only. Since a 'Fold' cannot be used to write back
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
398 -- there are no 'Lens' laws that apply.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
399 type Fold s a = forall f. (Gettable f, Applicative f) => (a -> f a) -> s -> f s
400
a142679 @basdirks haddocks: more linking
basdirks authored
401 -- | Every 'IndexedFold' is a valid 'Control.Lens.Fold.Fold' and can be used for 'Control.Lens.Getter.Getting'.
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
402 type IndexedFold i s a = forall p f. (Indexable i p, Applicative f, Gettable f) => p a (f a) -> s -> f s
6be7786 @ekmett Factoring out Control.Lens.Type
authored
403
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
404 -- | An 'IndexPreservingFold' can be used as a 'Fold', but when composed with an 'IndexedTraversal',
405 -- 'IndexedFold', or 'IndexedLens' yields an 'IndexedFold' respectively.
2e40da2 @ekmett switched to self-adjoint in signatures
authored
406 type IndexPreservingFold s a = forall p f. (SelfAdjoint p, Gettable f, Applicative f) => p a (f a) -> p s (f s)
3ce55f4 @ekmett Added 'Control.Lens.Equality'
authored
407
6be7786 @ekmett Factoring out Control.Lens.Type
authored
408 -------------------------------------------------------------------------------
409 -- Actions
410 -------------------------------------------------------------------------------
411
412 -- | An 'Action' is a 'Getter' enriched with access to a 'Monad' for side-effects.
413 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
414 -- Every 'Getter' can be used as an 'Action'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
415 --
416 -- You can compose an 'Action' with another 'Action' using ('Prelude..') from the @Prelude@.
417 type Action m s a = forall f r. Effective m r f => (a -> f a) -> s -> f s
418
419 -- | An 'IndexedAction' is an 'IndexedGetter' enriched with access to a 'Monad' for side-effects.
420 --
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
421 -- Every 'Getter' can be used as an 'Action'.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
422 --
423 -- You can compose an 'Action' with another 'Action' using ('Prelude..') from the @Prelude@.
424 type IndexedAction i m s a = forall p f r. (Indexable i p, Effective m r f) => p a (f a) -> s -> f s
425
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
426 -- | An 'IndexPreservingAction' can be used as a 'Action', but when composed with an 'IndexedTraversal',
427 -- 'IndexedFold', or 'IndexedLens' yields an 'IndexedMonadicFold', 'IndexedMonadicFold' or 'IndexedAction' respectively.
2e40da2 @ekmett switched to self-adjoint in signatures
authored
428 type IndexPreservingAction m s a = forall p f r. (SelfAdjoint p, Effective m r f) => p a (f a) -> p s (f s)
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
429
6be7786 @ekmett Factoring out Control.Lens.Type
authored
430 -------------------------------------------------------------------------------
431 -- MonadicFolds
432 -------------------------------------------------------------------------------
433
434 -- | A 'MonadicFold' is a 'Fold' enriched with access to a 'Monad' for side-effects.
435 --
436 -- Every 'Fold' can be used as a 'MonadicFold', that simply ignores the access to the 'Monad'.
437 --
438 -- You can compose a 'MonadicFold' with another 'MonadicFold' using ('Prelude..') from the @Prelude@.
439 type MonadicFold m s a = forall f r. (Effective m r f, Applicative f) => (a -> f a) -> s -> f s
440
441 -- | An 'IndexedMonadicFold' is an 'IndexedFold' enriched with access to a 'Monad' for side-effects.
442 --
443 -- Every 'IndexedFold' can be used as an 'IndexedMonadicFold', that simply ignores the access to the 'Monad'.
444 --
445 -- You can compose an 'IndexedMonadicFold' with another 'IndexedMonadicFold' using ('Prelude..') from the @Prelude@.
446 type IndexedMonadicFold i m s a = forall p f r. (Indexable i p, Effective m r f, Applicative f) => p a (f a) -> s -> f s
447
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
448 -- | An 'IndexPreservingFold' can be used as a 'Fold', but when composed with an 'IndexedTraversal',
449 -- 'IndexedFold', or 'IndexedLens' yields an 'IndexedFold' respectively.
2e40da2 @ekmett switched to self-adjoint in signatures
authored
450 type IndexPreservingMonadicFold m s a = forall p f r. (SelfAdjoint p, Effective m r f, Applicative f) => p a (f a) -> p s (f s)
918cd2d @ekmett IndexPreservingGetters, IndexPreservingFolds, IndexPreservingSetters,…
authored
451
6be7786 @ekmett Factoring out Control.Lens.Type
authored
452 -------------------------------------------------------------------------------
453 -- Simple Overloading
454 -------------------------------------------------------------------------------
455
456 -- | A 'Simple' 'Lens', 'Simple' 'Traversal', ... can
457 -- be used instead of a 'Lens','Traversal', ...
458 -- whenever the type variables don't change upon setting a value.
459 --
460 -- @
461 -- 'Data.Complex.Lens.imaginary' :: 'Simple' 'Lens' ('Data.Complex.Complex' a) a
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
462 -- 'Data.List.Lens._head' :: 'Simple' 'IndexedTraversal' 'Int' [a] a
6be7786 @ekmett Factoring out Control.Lens.Type
authored
463 -- @
464 --
465 -- Note: To use this alias in your own code with @'LensLike' f@ or
466 -- 'Setter', you may have to turn on @LiberalTypeSynonyms@.
467 --
468 -- This is commonly abbreviated as a \"prime\" marker, /e.g./ 'Lens'' = 'Simple' 'Lens'.
469 type Simple f s a = f s s a a
470
471 -- | @type 'LensLike' f s t a b = 'Overloading' (->) (->) f s t a b@
472 type Overloading p q f s t a b = p a (f b) -> q s (f t)
473
474 -- | @type 'Overloading'' p q f s a = 'Simple' ('Overloading' p q f) s a@
475 type Overloading' p q f s a = Overloading p q f s s a a
476
6687426 @ekmett more equalities and docfixes
authored
477 -- | @type 'LensLike' f s t a b = 'Overloaded' (->) f s t a b@
478 type Overloaded p f s t a b = p a (f b) -> p s (f t)
479
480 -- | @type 'Overloaded'' p q f s a = 'Simple' ('Overloaded' p q f) s a@
481 type Overloaded' p f s a = Overloaded p f s s a a
482
6be7786 @ekmett Factoring out Control.Lens.Type
authored
483 -- |
484 -- Many combinators that accept a 'Lens' can also accept a
485 -- 'Traversal' in limited situations.
486 --
487 -- They do so by specializing the type of 'Functor' that they require of the
488 -- caller.
489 --
490 -- If a function accepts a @'LensLike' f s t a b@ for some 'Functor' @f@,
491 -- then they may be passed a 'Lens'.
492 --
493 -- Further, if @f@ is an 'Applicative', they may also be passed a
494 -- 'Traversal'.
495 type LensLike f s t a b = (a -> f b) -> s -> f t
496
497 -- | @type 'LensLike'' f = 'Simple' ('LensLike' f)@
498 type LensLike' f s a = LensLike f s s a a
499
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
500 -- | Convenient alias for constructing indexed lenses and their ilk.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
501 type IndexedLensLike p f s t a b = p a (f b) -> s -> f t
502
d5b5a70 @basdirks haddocks: linking in Type
basdirks authored
503 -- | Convenient alias for constructing simple indexed lenses and their ilk.
6be7786 @ekmett Factoring out Control.Lens.Type
authored
504 type IndexedLensLike' p f s a = p a (f a) -> s -> f s
Something went wrong with that request. Please try again.