name: lens category: Data, Lenses version: 1.2 license: BSD3 cabal-version: >= 1.6 license-file: LICENSE author: Edward A. Kmett maintainer: Edward A. Kmett stability: provisional homepage: http://github.com/ekmett/lens/ bug-reports: http://github.com/ekmett/lens/issues copyright: Copyright (C) 2012 Edward A. Kmett synopsis: Lenses, Folds and Traversals description: The combinators in @Control.Lens@ provide a highly generic toolbox for composing families of getters, folds, traversals, setters and lenses. . /Getter/ . A @'Getter' a c@ is just any function @(a -> c)@, which we've flipped into continuation passing style, @(c -> r) -> a -> r@ and decorated with 'Const' to obtain . > type Getting r a b c d = (c -> Const r d) -> a -> Const r b . If we restrict access to knowledge about the type 'r' and can work for any d and b, we get: . > type Getter a c = forall r b d. Getting r a b c d . Everything you can do with a function, you can do with a 'Getter', but note that because of the continuation passing style (.) composes them in the opposite order. . Since it is only a function, every 'Getter' obviously only retrieves a single value for a given input. . /Fold/ . A @'Fold' a c@ is a generalization of something 'Foldable'. It allows you to extract multiple results from a container. A 'Foldable' container can be characterized by the behavior of @foldMap :: (Foldable t, Monoid m) => (c -> m) -> t c -> m@. Since we want to be able to work with monomorphic containers, we generalize this signature to @forall m. 'Monoid' m => (c -> m) -> a -> m@, and then decorate it with 'Const' to obtain . > type Fold a c = forall m b d. Monoid m => Getting m a b c d . Every 'Getter' is a valid 'Fold' that simply doesn't use the 'Monoid' it is passed. . Everything you can do with a 'Foldable' container, you can with with a 'Fold' and there are combinators that generalize the usual 'Foldable' operations in @Control.Lens@. . /Traversal/ . A @'Traversal' a b c d@ is a generalization of 'traverse' from 'Traversable'. It allows you to traverse over a structure and change out its contents with monadic or applicative side-effects. Starting from @'traverse' :: ('Traversable' t, 'Applicative' f) => (c -> f d) -> t c -> f (t d)@, we monomorphize the contents and result to obtain . > type Traversal a b c d = forall f. Applicative f => (c -> f d) -> a -> f b . While a 'Traversal' isn't quite a 'Fold', it _can_ be used for 'Getting' like a 'Fold', because given a 'Monoid' @m@, we have an 'Applicative' for @('Const' m)@. . Everything you can do with a 'Traversable' container, you can with with a 'Traversal', and there are combinators that generalize the usual 'Traversable' operations in @Control.Lens@. . /Setter/ . A @'Setter' a b c d@ is a generalization of 'fmap' from 'Functor'. It allows you to map into a structure and change out the contents, but it isn't strong enough to allow you to enumerate those contents. Starting with @fmap :: 'Functor' f => (c -> d) -> f c -> f d@ we monomorphize the type to obtain @(c -> d) -> a -> b@ and then decorate it with 'Identity' to obtain . > type Setter a b c d = (c -> Identity d) -> a -> Identity b . Every 'Traversal' is a valid 'Setter', since 'Identity' is 'Applicative'. . Everything you can do with a 'Functor', you can do with a 'Setter', and there are combinators that generalize the usual 'Functor' operations in @Control.Lens@. . /Lens/ . A @'Lens' a b c d@ is a purely functional reference. . While a 'Traversal' could be used for 'Getting' like a valid 'Fold', it wasn't a valid 'Getter'. To make the 'Applicative' for 'Const' it required a 'Monoid' for the argument we passed it, which a 'Getter' doesn't recieve. . However, the instance of 'Functor' for 'Const' requires no such thing. If we weaken the type requirement from 'Applicative' to 'Functor' for 'Traversal', we obtain . > type Lens a b c d = forall f. Functor f => (c -> f d) -> a -> f b . Every 'Lens' is a valid 'Setter', choosing @f@ = 'Identity'. . Every 'Lens' can be used for 'Getting' like a 'Fold' that doesn't use the 'Monoid' it is passed. . Every 'Lens' is a valid 'Traversal' that only uses the 'Functor' part of the 'Applicative' it is supplied. . Every 'Lens' can be used for 'Getting' like a valid 'Getter', choosing @f@ = 'Const' @r@ for an appropriate @r@ . Since every 'Lens' can be used for 'Getting' like a valid 'Getter' it follows that it must view exactly one element in the structure. . The lens laws follow from this property and the desire for it to act like a 'Functor' when used as a 'Setter'. . /Isomorphisms and Iso/ . Control.Isomorphic provides easy overloading of function application for isomorphisms and @Iso a b a d@ uses it to form isomorphism families that can be composed with other isomorphisms and with lenses, setters, folds, traversals and getters. . > type Iso a b c d = forall k f. (Isomorphic k, Functor f) => k (c -> f d) (a -> f b) . /Composition/ . Note that all of these types are type aliases, and you can compose these lenses with mere function compositon. . This is a generalization of the well-known trick for @(.).(.)@ or @fmap.fmap@, and their less well-known cousins @foldMap.foldMap@ @traverse.traverse@. It follows because each one is a function between values of type @(x -> f y)@ and the composition takes the intersection of supplied functionality for you automatically! . /Lens Families/ . For a longer description of why you should care about lenses, and an overview of why we use 4 parameters a, b, c, and d instead of just 2, see . . Sometimes you won't need the flexibility those extra parameters afford you and you can use . > type Simple f a b = f a a b b . to describe a 'Simple' 'Setter', 'Simple' 'Traversal', 'Simple' 'Lens' or 'Simple' 'Iso'. . /Avoiding Dependencies/ . Note: If you merely want your library to /provide/ lenses you may not have to actually import /any/ lens library at all. For, say, a @'Simple' 'Lens' Bar Foo@, just export a function with the signature: . > foo :: Functor f => (Foo -> f Foo) -> Bar -> f Bar . and then you can compose it with other lenses using nothing more than @(.)@ from the Prelude. . /Deriving Lenses/ . You can derive lenses automatically for many data types using 'Control.Lens.TH', and if a container is fully characterized by its lenses, you can use 'Control.Lens.Representable' to automatically derive 'Functor', 'Applicative', 'Monad', and 'Derivable'. build-type: Simple tested-with: GHC == 7.4.1 extra-source-files: .travis.yml source-repository head type: git location: git://github.com/ekmett/lens.git library exposed-modules: Control.Exception.Lens Control.Isomorphic Control.Lens Control.Lens.Internal Control.Lens.Representable Control.Lens.TH Control.Parallel.Strategies.Lens Control.Seq.Lens Data.Array.Lens Data.Bits.Lens Data.ByteString.Lens Data.ByteString.Lazy.Lens Data.Complex.Lens Data.Dynamic.Lens Data.Map.Lens Data.IntMap.Lens Data.IntSet.Lens Data.Sequence.Lens Data.Set.Lens Data.Text.Lens Data.Text.Lazy.Lens Data.Time.Calendar.Lens Data.Tree.Lens -- All dependencies are in the Haskell Platform build-depends: array == 0.4.*, base == 4.*, bytestring == 0.9.*, containers >= 0.3 && < 0.6, mtl >= 2.1.1 && < 2.2, parallel == 3.2.*, template-haskell >= 2.4 && < 2.8, text == 0.11.*, time == 1.4.*, transformers >= 0.2 && < 0.4 other-extensions: CPP DeriveDataTypeable LiberalTypeSynonyms MultiParamTypeClasses Rank2Types RankNTypes TemplateHaskell TypeOperators if (impl(ghc>=7.4)) other-extensions: Trustworthy ghc-options: -Wall -fwarn-tabs -O2 -fdicts-cheap -funbox-strict-fields hs-source-dirs: src