Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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