microlens 0.3.5.1 → 0.4.0.0
raw patch · 6 files changed
+174/−94 lines, 6 files
Files
- CHANGELOG.md +4/−2
- microlens.cabal +5/−3
- src/Lens/Micro.hs +100/−22
- src/Lens/Micro/Extras.hs +4/−43
- src/Lens/Micro/Internal.hs +7/−4
- src/Lens/Micro/Type.hs +54/−20
CHANGELOG.md view
@@ -1,6 +1,8 @@-# 0.3.5.1+# 0.4.0.0 -* Backported the fix for the bug that wasn't letting the package compile with GHC 8.0 (see issue #63).+* Added `folding`.+* Renamed `Getter` and `Fold` to `SimpleGetter` and `SimpleFold` and put them into `Lens.Micro`. Genuine `Getter` and `Fold` are available in microlens-contra.+* Replaced `Applicative (Const r)` constraints with `Monoid r` because it's the same thing but easier to understand. # 0.3.5.0
microlens.cabal view
@@ -1,5 +1,5 @@ name: microlens-version: 0.3.5.1+version: 0.4.0.0 synopsis: A tiny part of the lens library with no dependencies description: This is an extract from <http://hackage.haskell.org/package/lens lens> (with no dependencies). It's not a toy lenses library, unsuitable for “real world”, but merely a small one. It is compatible with lens, and should have same performance. It also has better documentation.@@ -16,9 +16,11 @@ . * if you want a library with a clean, understandable implementation (in which case you're looking for <http://hackage.haskell.org/package/lens-simple lens-simple>) .- If you're writing an application which uses lenses more extensively, look at <http://hackage.haskell.org/package/microlens-platform microlens-platform> – it combines features of all other microlens packages (<http://hackage.haskell.org/package/microlens-mtl microlens-mtl>, <http://hackage.haskell.org/package/microlens-th microlens-th>, <http://hackage.haskell.org/package/microlens-ghc microlens-ghc>).+ If you're writing an application which uses lenses more extensively, look at <http://hackage.haskell.org/package/microlens-platform microlens-platform> – it combines features of most other microlens packages (<http://hackage.haskell.org/package/microlens-mtl microlens-mtl>, <http://hackage.haskell.org/package/microlens-th microlens-th>, <http://hackage.haskell.org/package/microlens-ghc microlens-ghc>). .- There's a longer readme <https://github.com/aelve/microlens#readme on Github>, you should read it if you're still interested about using this library.+ If you want to export getters or folds and don't mind the <http://hackage.haskell.org/package/contravariant contravariant> dependency, please consider using <http://hackage.haskell.org/package/microlens-contra microlens-contra>.+ .+ There's a longer readme <https://github.com/aelve/microlens#readme on Github>, you should read it if you're interested about using this library. . If you haven't ever used lenses before, read <http://hackage.haskell.org/package/lens-tutorial/docs/Control-Lens-Tutorial.html this tutorial>. (It's for lens, but it applies to microlens just as well.) .
src/Lens/Micro.hs view
@@ -5,7 +5,6 @@ UndecidableInstances, RankNTypes, ScopedTypeVariables,-MonoLocalBinds, Trustworthy #-} @@ -15,7 +14,8 @@ (&), -- $ampersand-note - -- * Setting (applying a function to values)+ -- * Setter: modifies something in a structure+ -- $setters-note ASetter, ASetter', sets, (%~), over,@@ -23,28 +23,31 @@ (<%~), (<<%~), (<<.~), mapped, - -- * Getting (retrieving a value)+ -- * Getter: extracts a value from a structure -- $getters-note+ SimpleGetter, Getting, (^.), to, - -- * Folds (getters returning multiple elements)+ -- * Fold: extracts multiple elements -- $folds-note+ SimpleFold, (^..), toListOf, (^?), (^?!),- folded, has,+ folded,+ folding, - -- * Lenses (setters and getters at once)+ -- * Lens: a combined getter-and-setter Lens, Lens', lens, at, non, _1, _2, _3, _4, _5, - -- * Traversals (lenses iterating over several elements)+ -- * Traversal: a lens iterating over several elements Traversal, Traversal', failing, filtered,@@ -54,7 +57,7 @@ ix, _head, _tail, _init, _last, - -- * Prisms (traversals iterating over at most 1 element)+ -- * Prism: a traversal iterating over at most 1 element -- $prisms-note _Left, _Right, _Just, _Nothing,@@ -73,6 +76,7 @@ import Data.Functor.Identity import Data.Monoid import Data.Maybe+import qualified Data.Foldable as F #if __GLASGOW_HASKELL__ >= 710 import Data.Function ((&))@@ -121,6 +125,57 @@ -- Setting ----------------------------------------------------------------- +{- $setters-note++A setter is, broadly speaking, something that lets you modify a part of some value. Most likely you already know some setters:++ * @'Control.Arrow.first' :: (a -> b) -> (a, x) -> (b, x)@++ (modifies 1st element of a pair; corresponds to 'Lens.Micro._1')++ * @'Control.Arrow.left' :: (a -> b) -> 'Either' a x -> 'Either' b x@++ (modifies left branch of 'Either'; corresponds to 'Lens.Micro._Left')++ * @'map' :: (a -> b) -> [a] -> [b]@++ (modifies every element in a list; corresponds to 'Lens.Micro.mapped')++As you see, a setter takes a function, a value, and applies the function to some part (or several parts) of the value. Moreover, setters can be pretty specific – for instance, a function that modifies the 3rd element of a list is a setter too:++@+-- Modify 3rd element in a list, if present.+modify3rd :: (a -> a) -> [a] -> [a]+modify3rd f (a:b:c:xs) = a : b : f c : xs+modify3rd _ xs = xs+@++A nice thing about setters is that they compose easily – you can write @'map' '.' 'Control.Arrow.left'@ and it would be a function that takes a list of 'Either's and modifies all of them that are 'Left's.++This library provides its own type for setters – 'ASetter'; it's needed so that some functions in this library (like '_1') would be usable both as setters and as getters. You can turn an ordinary function like 'map' to a “lensy” setter with 'sets'.++To apply a setter to a value, use ('%~') or 'over':++>>> [1,2,3] & mapped %~ succ+[2,3,4]+>>> over _head toUpper "jane"+"Jane"++To modify a value deeper inside the structure, use ('.'):++>>> ["abc","def","ghi"] & ix 1 . ix 2 %~ toUpper+["abc","deF","ghi"]++To set a value instead of modifying it, use 'set' or ('.~'):++>>> "abc" & mapped .~ 'x'+"xxx"+>>> set _2 'X' ('a','b','c')+('a','X','c')++It's also possible to get both the old and the new value back – see ('<%~') and ('<<%~').+-}+ {- | ('%~') applies a function to the target; an alternative explanation is that it is an inverse of 'sets', which turns a setter into an ordinary function. @'mapped' '%~' 'reverse'@ is the same thing as @'fmap' 'reverse'@. @@ -169,10 +224,11 @@ {-# INLINE over #-} {- |-('.~') assigns a value to the target. These are equivalent:+('.~') assigns a value to the target. It's the same thing as using ('%~') with 'const': -* @l '.~' x@-* @l '%~' 'const' x@+@+l '.~' x = l '%~' 'const' x+@ See 'set' if you want a non-operator synonym. @@ -238,6 +294,8 @@ ('<%~') :: 'Lens' s t a b -> (a -> b) -> s -> (b, t) ('<%~') :: 'Monoid' b => 'Traversal' s t a b -> (a -> b) -> s -> (b, t) @++Since it does getting in addition to setting, you can't use it with 'ASetter' (but you can use it with lens and traversals). -} (<%~) :: LensLike ((,) b) s t a b -> (a -> b) -> s -> (b, t) (<%~) l f = l (join (,) . f)@@ -281,11 +339,21 @@ {- $getters-note -Getters are a not-entirely-obvious way to use lenses to /carry out/ information from a structure (instead of changing something inside the structure). Any lens or traversal is a getter.+A getter extracts something from a value; in fact, any function is a getter. However, same as with setters, this library uses a special type for getters so that functions like '_1' would be usable both as a setter and a getter. An ordinary function can be turned into a getter with 'to'. -For details, see the documentation for 'Getting'.+Using a getter is done with ('^.') or 'Lens.Micro.Extras.view' from "Lens.Micro.Extras": -Including @Getter@ from lens is impossible, as then this package would have to depend on <http://hackage.haskell.org/package/contravariant contravariant> and it's a big dependency. If you absolutely need it, there's a slightly less polymorphic 'Lens.Micro.Extras.Getter' present in "Lens.Micro.Extras".+>>> ('x','y') ^. _1+'x'+>>> view (ix 2) [0..5]+2++Getters can be composed with ('.'):++>>> [(1,2),(3,4),(5,6)] ^. ix 1 . _2+4++A getter always returns exactly 1 element (getters that can return more than one element are called folds and are present in this library as well). -} {- |@@ -338,7 +406,7 @@ value ^. _1 . to field . at 2 @ -}-to :: (s -> a) -> Getting r s a+to :: (s -> a) -> SimpleGetter s a to k f = phantom . f . k {-# INLINE to #-} @@ -346,25 +414,27 @@ {- $folds-note -Folds are getters that can traverse more than one element (or no elements at all). The only fold here which isn't simultaneously a 'Traversal' is 'folded' (traversals are folds that also can modify elements they're traversing).+Folds are getters that can return more than one element (or no elements at all). <http://comonad.com/reader/2015/free-monoids-in-haskell/ Except for some rare cases>, a fold is the same thing as @(s -> [a])@; you can use 'folding' to turn any function of type @(s -> f a)@ (where @f@ is 'F.Foldable') into a fold. -You can apply folds to values by using operators like ('^..'), ('^?'), etc:+Folds can be applied to values by using operators like ('^..'), ('^?'), etc: >>> (1,2) ^.. both [1,2] A nice thing about folds is that you can combine them with ('Data.Monoid.<>') to concatenate their outputs: ->>> (1,2,3) ^.. (_2 <> _1) -- in reversed order because why not+>>> (1,2,3) ^.. (_2 <> _1) [2,1] -You can build more complicated getters with it when 'each' would be unhelpful:+When you need to get all elements of the same type in a complicated structure, ('Data.Monoid.<>') can be more helpful than 'each': >>> ([1,2], 3, [Nothing, Just 4]) ^.. (_1.each <> _2 <> _3.each._Just) [1,2,3,4] -It plays nicely with ('^?'), too:+(Just like setters and getters before, folds can be composed with ('.').) +The ('Data.Monoid.<>') trick works nicely with ('^?'), too. For instance, if you want to get the 9th element of the list, but would be fine with 5th too if the list is too short, you could combine @ix 9@ and @ix 5@:+ >>> [0..9] ^? (ix 9 <> ix 5) Just 9 >>> [0..8] ^? (ix 9 <> ix 5)@@ -373,8 +443,6 @@ Nothing (Unfortunately, this trick won't help you with setting or modifying.)--Just like with @Getter@, including @Fold@ from lens in this module is impossible. If you absolutely need it, there's a slightly less polymorphic 'Lens.Micro.Extras.Fold' present in "Lens.Micro.Extras". -} {- |@@ -455,6 +523,16 @@ has :: Getting Any s a -> s -> Bool has l = getAny #. foldMapOf l (\_ -> Any True) {-# INLINE has #-}++{- |+'folding' creates a fold out of any function that returns a 'F.Foldable' container (for instance, a list):++>>> [1..5] ^.. folding tail+[2,3,4,5]+-}+folding :: F.Foldable f => (s -> f a) -> SimpleFold s a+folding sfa agb = phantom . F.traverse_ agb . sfa+{-# INLINE folding #-} -- Lenses ------------------------------------------------------------------
src/Lens/Micro/Extras.hs view
@@ -1,19 +1,12 @@ {-# LANGUAGE-RankNTypes,-FlexibleContexts, Trustworthy #-} -{- |-This module provides functions and types that are inferior to their lens counterparts.--} module Lens.Micro.Extras ( view, preview,- Getter,- Fold, ) where @@ -31,13 +24,13 @@ >>> view _1 (1, 2) 1 -The reason it's in this module is that @view@ in lens has a more general signature:+The reason it's not in "Lens.Micro" is that @view@ in lens has a more general signature: @ view :: MonadReader s m => Getting a s a -> m a @ -So, you would be able to use this 'view' with functions, but not in various reader monads. For most people this shouldn't be an issue.+So, you would be able to use this 'view' with functions, but not in various reader monads. For most people this shouldn't be an issue; if it is for you, use @view@ from <http://hackage.haskell.org/package/microlens-mtl microlens-mtl>. -} view :: Getting a s a -> s -> a view l = getConst #. l Const@@ -49,46 +42,14 @@ >>> preview _head [1,2,3] Just 1 -The reason it's in this module is that @preview@ in lens has a more general signature:+The reason it's not in "Lens.Micro" is that @preview@ in lens has a more general signature: @ preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a) @ -So, just like with 'view', you would be able to use this 'preview' with functions, but not in reader monads.+Just like with 'view', you would be able to use this 'preview' with functions, but not in reader monads; if this is an issue for you, use @preview@ from <http://hackage.haskell.org/package/microlens-mtl microlens-mtl>. -} preview :: Getting (First a) s a -> s -> Maybe a preview l = getFirst #. foldMapOf l (First #. Just) {-# INLINE preview #-}--{- |-A @Getter s a@ extracts @a@ from @s@; so, it's the same thing as @(s -> a)@, but you can use it in lens chains. For details, see 'Getting'.--The reason it's in this module is that the actual @Getter@ from lens is more general:--@-type Getter s a =- forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s-@--I'm not currently aware of any functions that take lens's @Getter@ but won't accept this @Getter@, but you should try to avoid exporting 'Getter's anyway to minimise confusion.--Lens users: you can convert fake getters to real getters by applying @to . view@ to them.--}-type Getter s a = forall r. Getting r s a--{- |-A @Fold s a@ extracts several @a@s from @s@; so, it's pretty much the same thing as @(s -> [a])@, but you can use it with lens operators.--The reason it's in this module is that the actual @Fold@ from lens is more general:--@-type Fold s a =- forall f. (Contravariant f, Applicative f) => (a -> f a) -> s -> f s-@--I'm only aware of 2 functions that accept lens's @Fold@ but won't accept this @Fold@ – they are @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Fold.html#v:foldByOf foldByOf>@ and @<http://hackage.haskell.org/package/lens-4.13/docs/Control-Lens-Fold.html#v:foldMapByOf foldMapByOf>@. They aren't used often, but you should try to avoid exporting 'Fold's anyway to minimise confusion (and to prevent people cursing you when they want to use @foldByOf@ with your fold).--Lens users: you can convert fake folds to real folds by applying @folded . toListOf@ to them.--}-type Fold s a = forall r. Applicative (Const r) => Getting r s a
src/Lens/Micro/Internal.hs view
@@ -15,8 +15,11 @@ {- |-This module is needed to give other packages from the microlens family (like <http://hackage.haskell.org/package/microlens-ghc microlens-ghc>) access to functions and classes that don't need to be exported from "Lens.Micro" (because they just clutter the namespace). Also, okay, uh, e.g. 'traversed' is here because otherwise there'd be a dependency cycle.+This module is needed to give other packages from the microlens family (like <http://hackage.haskell.org/package/microlens-ghc microlens-ghc>) access to functions and classes that don't need to be exported from "Lens.Micro" (because they just clutter the namespace). Also: + * 'traversed' is here because otherwise there'd be a dependency cycle+ * 'sets' is here because it's used in RULEs+ Classes like 'Each', 'Ixed', etc are provided for convenience – you're not supposed to export functions that work on all members of 'Ixed', for instance. Only microlens can do that. You mustn't declare instances of those classes for other types, either; these classes are incompatible with lens's classes, and by doing so you would divide the ecosystem. If you absolutely need to define an instance (e.g. for internal use), only do it for your own types, because otherwise I might add an instance to one of the microlens packages later and if our instances are different it might lead to subtle bugs.@@ -90,11 +93,11 @@ 'folded' is a fold for anything 'Foldable'. In a way, it's an opposite of 'mapped' – the most powerful getter, but can't be used as a setter. -}-folded :: (Foldable f, Applicative (Const r)) => Getting r (f a) a+folded :: Foldable f => SimpleFold (f a) a folded = foldring F.foldr {-# INLINE folded #-} -foldring :: (Applicative (Const r)) => ((a -> Const r a -> Const r a) -> Const r a -> s -> Const r a) -> (a -> Const r b) -> s -> Const r t+foldring :: Monoid r => ((a -> Const r a -> Const r a) -> Const r a -> s -> Const r a) -> (a -> Const r b) -> s -> Const r t foldring fr f = phantom . fr (\a fa -> f a *> fa) noEffect {-# INLINE foldring #-} @@ -122,7 +125,7 @@ phantom = Const #. getConst {-# INLINE phantom #-} -noEffect :: Applicative (Const r) => Const r a+noEffect :: Monoid r => Const r a noEffect = phantom (pure ()) {-# INLINE noEffect #-}
src/Lens/Micro/Type.hs view
@@ -1,16 +1,18 @@ {-# LANGUAGE+CPP, RankNTypes, Safe #-} {- |-This module provides just the types ('Lens', 'Traversal', etc). It's needed to break the dependency cycle – "Lens.Micro" depends on "Lens.Micro.Classes", but "Lens.Micro.Classes" needs types like 'Lens', so 'Lens' can't be defined in "Lens.Micro".+This module provides just the types ('Lens', 'Traversal', etc). It's needed to break the dependency cycle – "Lens.Micro" depends on "Lens.Micro.Internal", but "Lens.Micro.Internal" needs types like 'Lens', so 'Lens' can't be defined in "Lens.Micro". -} module Lens.Micro.Type ( ASetter, ASetter',- Getting,+ SimpleGetter, Getting,+ SimpleFold, Lens, Lens', Traversal, Traversal', LensLike, LensLike',@@ -21,7 +23,11 @@ import Control.Applicative import Data.Functor.Identity +#if __GLASGOW_HASKELL__ < 710+import Data.Monoid+#endif + {- | @ASetter s t a b@ is something that turns a function modifying a value into a function modifying a /structure/. If you ignore 'Identity' (as @Identity a@ is the same thing as @a@), the type is: @@ -29,45 +35,73 @@ type ASetter s t a b = (a -> b) -> s -> t @ -This means that examples of setters you might've already seen are:+The reason 'Identity' is used here is for 'ASetter' to be composable with other types, such as 'Lens'. - * @'map' :: (a -> b) -> [a] -> [b]@+Technically, if you're writing a library, you shouldn't use this type for setters you are exporting from your library; the right type to use is @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Setter.html#t:Setter Setter>@, but it is not provided by this package (because then it'd have to depend on <http://hackage.haskell.org/package/distributive distributive>). It's completely alright, however, to export functions which take an 'ASetter' as an argument.+-}+type ASetter s t a b = (a -> Identity b) -> s -> Identity t - (which corresponds to 'Lens.Micro.mapped')+{- |+This is a type alias for monomorphic setters which don't change the type of the container (or of the value inside). It's useful more often than the same type in lens, because we can't provide real setters and so it does the job of both @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Setter.html#t:ASetter-39- ASetter'>@ and @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Setter.html#t:Setter-39- Setter'>@.+-}+type ASetter' s a = ASetter s s a a - * @'fmap' :: 'Functor' f => (a -> b) -> f a -> f b@+{- |+A @SimpleGetter s a@ extracts @a@ from @s@; so, it's the same thing as @(s -> a)@, but you can use it in lens chains because its type looks like this: - (which corresponds to 'Lens.Micro.mapped' as well)+@+type SimpleGetter s a =+ forall r. (a -> Const r a) -> s -> Const r s+@ - * @'Control.Arrow.first' :: (a -> b) -> (a, x) -> (b, x)@+Since @Const r@ is a functor, 'SimpleGetter' has the same shape as other lens types and can be composed with them. To get @(s -> a)@ out of a 'SimpleGetter', choose @r ~ a@ and feed @Const :: a -> Const a a@ to the getter: - (which corresponds to 'Lens.Micro._1')+@+-- the actual signature is more permissive:+-- 'Lens.Micro.Extras.view' :: 'Getting' a s a -> s -> a+'Lens.Micro.Extras.view' :: 'SimpleGetter' s a -> s -> a+'Lens.Micro.Extras.view' getter = 'getConst' . getter 'Const'+@ - * @'Control.Arrow.left' :: (a -> b) -> 'Either' a x -> 'Either' b x@+The actual @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Getter.html#t:Getter Getter>@ from lens is more general: - (which corresponds to 'Lens.Micro._Left')+@+type Getter s a =+ forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s+@ -The reason 'Identity' is used here is for 'ASetter' to be composable with other types, such as 'Lens'.+I'm not currently aware of any functions that take lens's @Getter@ but won't accept 'SimpleGetter', but you should try to avoid exporting 'SimpleGetter's anyway to minimise confusion. Alternatively, look at <http://hackage.haskell.org/package/microlens-contra microlens-contra>, which provides a fully lens-compatible @Getter@. -Technically, if you're writing a library, you shouldn't use this type for setters you are exporting from your library; the right type to use is @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Setter.html#t:Setter Setter>@, but it is not provided by this package (because then we'd have to depend on <http://hackage.haskell.org/package/distributive distributive>). It's completely alright, however, to export functions which take an 'ASetter' as an argument.+Lens users: you can convert a 'SimpleGetter' to @Getter@ by applying @to . view@ to it. -}-type ASetter s t a b = (a -> Identity b) -> s -> Identity t+type SimpleGetter s a = forall r. Getting r s a {- |-This is a type alias for monomorphic setters which don't change the type of the container (or of the value inside). It's useful more often than the same type in lens, because we can't provide real setters and so it does the job of both @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Setter.html#t:ASetter-39- ASetter'>@ and @<http://hackage.haskell.org/package/lens/docs/Control-Lens-Setter.html#t:Setter-39- Setter'>@.+Functions that operate on getters and folds – such as ('Lens.Micro.^.'), ('Lens.Micro.^..'), ('Lens.Micro.^?') – use @Getter r s a@ (with different values of @r@) to describe what kind of result they need. For instance, ('Lens.Micro.^.') needs the getter to be able to return a single value, and so it accepts a getter of type @Getting a s a@. ('Lens.Micro.^..') wants the getter to gather values together, so it uses @Getting (Endo [a]) s a@ (it could've used @Getting [a] s a@ instead, but it's faster with 'Data.Monoid.Endo'). The choice of @r@ depends on what you want to do with elements you're extracting from @s@. -}-type ASetter' s a = ASetter s s a a+type Getting r s a = (a -> Const r a) -> s -> Const r s {- |-If you take a lens or a traversal and choose @'Const' r@ as your functor, you will get @Getting r s a@. This can be used to get something out of the structure instead of modifying it:+A @SimpleFold s a@ extracts several @a@s from @s@; so, it's pretty much the same thing as @(s -> [a])@, but you can use it with lens operators. +The actual @Fold@ from lens is more general:+ @-s 'Lens.Micro.^.' l = 'getConst' (l 'Const' s)+type Fold s a =+ forall f. (Contravariant f, Applicative f) => (a -> f a) -> s -> f s @ -Functions that operate on getters – such as ('Lens.Micro.^.'), ('Lens.Micro.^..'), ('Lens.Micro.^?') – use @Getter r s a@ (with different values of @r@) to describe what kind of getter they need. For instance, ('Lens.Micro.^.') needs the getter to be able to return a single value, and so it accepts a getter of type @Getting a s a@. ('Lens.Micro.^..') wants the getter to gather values together, so it uses @Getting (Endo [a]) s a@ (it could've used @Getting [a] s a@ instead, but it's faster with 'Data.Monoid.Endo'). The choice of @r@ depends on what you want to do with elements you're extracting from @s@.+There are several functions in lens that accept lens's @Fold@ but won't accept 'SimpleFold'; I'm aware of+@<http://hackage.haskell.org/package/lens/docs/Control-Lens-Fold.html#v:takingWhile takingWhile>@,+@<http://hackage.haskell.org/package/lens/docs/Control-Lens-Fold.html#v:droppingWhile droppingWhile>@,+@<http://hackage.haskell.org/package/lens/docs/Control-Lens-Fold.html#v:backwards backwards>@,+@<http://hackage.haskell.org/package/lens/docs/Control-Lens-Fold.html#v:foldByOf foldByOf>@,+@<http://hackage.haskell.org/package/lens/docs/Control-Lens-Fold.html#v:foldMapByOf foldMapByOf>@.+For this reason, try not to export 'SimpleFold's if at all possible. <http://hackage.haskell.org/package/microlens-contra microlens-contra> provides a fully lens-compatible @Fold@.++Lens users: you can convert a 'SimpleFold' to @Fold@ by applying @folded . toListOf@ to it. -}-type Getting r s a = (a -> Const r a) -> s -> Const r s+type SimpleFold s a = forall r. Monoid r => Getting r s a {- | Lenses in a nutshell: use ('Lens.Micro.^.') to get, ('Lens.Micro..~') to set, ('Lens.Micro.%~') to modify. ('.') composes lenses (i.e. if a @B@ is a part of @A@, and a @C@ is a part of in @B@, then @b.c@ lets you operate on @C@ inside @A@). You can create lenses with 'Lens.Micro.lens', or you can write them by hand (see below).