Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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