packages feed

lens-family 0.1.0 → 1.0.0

raw patch · 7 files changed

+492/−133 lines, 7 filesdep ~lens-family-core

Dependency ranges changed: lens-family-core

Files

CHANGELOG view
@@ -1,3 +1,8 @@+1.0.0 (Changes from 0.1.0)+=========================+* added support for folds and traversals+* renamed all functions to be mostly compatible with the lexicon from lens.+ 0.1.0 (Changes from 0.0.1) ========================= * added project and sec
lens-family.cabal view
@@ -1,30 +1,34 @@ name:               lens-family category:           Data, Lenses-version:            0.1.0+version:            1.0.0 license:            BSD3 cabal-version:      >= 1.6 license-file:       LICENSE author:             Russell O'Connor maintainer:         Russell O'Connor <roconnor@theorem.ca>-stability:          expermimental-copyright:          Copyright (C) 2012 Russell O'Connor+stability:          experimental+copyright:          Copyright (C) 2012,2013 Russell O'Connor synopsis:           Lens Families description:        Lens Families build-type:         Simple extra-source-files: CHANGELOG-description:        This package provides optimal first class functional references+description:        This package provides first class functional references.                     In addition to the usual operations of getting, setting and composition, plus integration with monad state, lens families provide some unique features:                     .                     * Polymorphic updating                     .+                    * Traversals+                    .                     * Cast projection functions to read-only lenses                     .-                    * Cast semantic editor combinators to modify-only lenses+                    * Cast \"toList\" functions to read-only traversals+                    .+                    * Cast semantic editor combinators to modify-only traversals.  source-repository head   type:     darcs   location: http://r6.ca/lens-family-  + library   extensions:       Rank2Types   build-depends:@@ -32,7 +36,7 @@     containers           >= 0.3     && < 0.6,     transformers         >= 0.2.0   && < 0.4,     mtl                  >= 2.1     && < 2.2,-    lens-family-core     >= 0.1     && < 0.2+    lens-family-core     >= 1.0     && < 1.1    exposed-modules:     Lens.Family2.Unchecked
src/Lens/Family2.hs view
@@ -1,5 +1,178 @@-module Lens.Family2-  ( module Lens.Family+{-# LANGUAGE Rank2Types #-}+-- | This is the main module for end-users of lens-families.+-- If you are not building your own lenses or traversals, but just using functional references made by others, this is the only module you need.+module Lens.Family2 (+-- * Lenses+--+-- | This module provides 'LF.^.' for accessing fields and 'LF..~' and 'LF.%~' for setting and modifying fields.+-- Lenses are composed with `Prelude..` from the @Prelude@ and `Prelude.id` is the identity lens.+--+-- Lens composition in this library enjoys the following identities.+--+-- * @x^.l1.l2 === x^.l1^.l2@+--+-- * @l1.l2 %~ f === l1 %~ l2 %~ f@+--+-- The identity lens behaves as follows.+--+-- * @x^.id === x@+--+-- * @id %~ f === f@+--+-- The 'LF.&' operator, allows for a convenient way to sequence record updating:+--+-- @record & l1 .~ value1 & l2 .~ value2@+--+-- Lenses are implemented in van Laarhoven style.+-- Lenses have type @'Functor' f => (b -> f b) -> a -> f a@ and lens families have type @'Functor' f => (b i -> f (b j)) -> a i -> f (a j)@.+--+-- Keep in mind that lenses and lens families can be used directly for functorial updates.+-- For example, @_2 id@ gives you strength.+--+-- > _2 id :: Functor f => (a, f b) -> f (a, b)+--+-- Here is an example of code that uses the 'Maybe' functor to preserves sharing during update when possible.+--+-- > -- | 'sharedUpdate' returns the *identical* object if the update doesn't change anything.+-- > -- This is useful for preserving sharing.+-- > sharedUpdate :: Eq b => LensLike' Maybe a b -> (b -> b) -> a -> a+-- > sharedUpdate l f a = fromMaybe a (l f' a)+-- >  where+-- >   f' b | fb == b  = Nothing+-- >        | otherwise = Just fb+-- >    where+-- >     fb = f b++-- * Traversals+--+-- | 'LF.^.' can be used with traversals to access monoidal fields.+-- The result will be a 'Data.Monid.mconcat' of all the fields referenced.+-- The various @fooOf@ functions can be used to access different monoidal summaries of some kinds of values.+--+-- '^?' can be used to access the first value of a traverasal.+-- 'Nothing' is returned when the traversal has no references.+--+-- '^..' can be used with a traversals and will return a list of all fields referenced.+--+-- When 'LF..~' is used with a traveral, all referenced fields will be set to the same value, and when 'LF.%~' is used with a traversal, all referenced fields will be modified with the same function.+--+-- Like lenses, traversals can be composed with '.', and because every lens is automatically a traversal, lenses and traversals can be composed with '.' yielding a traversal.+--+-- Traversals are implemented in van Laarhoven style.+-- Traversals have type @'Applicative' f => (b -> f b) -> a -> f a@ and traversal families have type @'Applicative' f => (b i -> f (b j)) -> a i -> f (a j)@.+--+-- For stock lenses and traversals, see "Lens.Family2.Stock".+--+-- To build your own lenses and traversals, see "Lens.Family2.Unchecked".+--+-- References:+--+-- * <http://www.twanvl.nl/blog/haskell/cps-functional-references>+--+-- * <http://r6.ca/blog/20120623T104901Z.html>+--+-- * <http://comonad.com/reader/2012/mirrored-lenses/>+--+-- * <http://conal.net/blog/posts/semantic-editor-combinators>++-- * Documentation+    to, LF.view, (LF.^.)+  , folding, LF.views, (^..), (^?)+  , toListOf, allOf, anyOf, firstOf, lastOf, sumOf, productOf+  , lengthOf, nullOf+  , LF.backwards+  , LF.over, (LF.%~), LF.set, (LF..~)+  , (LF.&)+  -- * Pseudo-imperatives+  , (LF.+~), (LF.*~), (LF.-~), (LF.//~), (LF.&&~), (LF.||~), (LF.<>~)+  -- * Types+  , Lens, Lens'+  , Traversal, Traversal'+  , Getter, Getter'+  , Fold, Fold'+  , LF.Setter, LF.Setter'+  , LF.LensLike, LF.LensLike'+  , LF.FoldLike, LF.FoldLike'+  , LF.Getting, LF.Setting+  , LF.Phantom+-- * Re-exports+  , Applicative, Foldable, Monoid+  , LF.Backwards   ) where -import Lens.Family+import Control.Applicative (Applicative)+import Data.Foldable (Foldable)+import Data.Monoid (Monoid)+import qualified Lens.Family as LF+import Lens.Family2.Unchecked (Lens, Lens', Traversal, Traversal')++type Fold a a' b b' = forall f. (LF.Phantom f, Applicative f) => LF.LensLike f a a' b b'+type Fold' a b = Fold a a b b++type Getter a a' b b' = forall f. LF.Phantom f => LF.LensLike f a a' b b'+type Getter' a b = Fold a a b b++-- |'to' promotes a projection function to a read-only lens called a getter.+-- To demote a lens to a projection function, use the section @(^.l)@ or @view l@.+--+-- >>> (3 :+ 4, "example")^._1.to(abs)+-- 5.0 :+ 0.0+to :: (a -> b) -> Getter a a' b b'+to = LF.to++-- | 'folding' promotes a \"toList\" function to a read-only traversal called a fold.+--+-- To demote a traversal or fold to a \"toList\" function use the section @(^..l)@ or @toListOf l@.+folding :: Foldable f => (a -> f b) -> Fold a a' b b'+folding = LF.folding++-- | Returns a list of all of the referenced values in order.+toListOf :: Fold a a' b b' -> a -> [b]+toListOf l = LF.toListOf l++-- | Returns true if all of the referenced values satisfy the given predicate.+allOf :: Fold a a' b b' -> (b -> Bool) -> a -> Bool+allOf l = LF.allOf l++anyOf :: Fold a a' b b' -> (b -> Bool) -> a -> Bool+anyOf l = LF.anyOf l++-- | Returns 'Just' the first referenced value.+-- Returns 'Nothing' if there are no referenced values.+-- See '^?' for an infix version of 'firstOf'+firstOf :: Fold a a' b b' -> a -> Maybe b+firstOf l = LF.firstOf l++-- | Returns 'Just' the last referenced value.+-- Returns 'Nothing' if there are no referenced values.+lastOf :: Fold a a' b b' -> a -> Maybe b+lastOf l = LF.lastOf l++-- | Returns the sum of all the referenced values.+sumOf :: Num b => Fold a a' b b' -> a -> b+sumOf l = LF.sumOf l++-- | Returns the product of all the referenced values.+productOf :: Num b => Fold a a' b b' -> a -> b+productOf l = LF.productOf l++-- | Counts the number of references in a traversal or fold for the input.+lengthOf :: Num r => Fold a a' b b' -> a -> r+lengthOf l = LF.lengthOf l++-- | Returns true if the number of references in the input is zero.+nullOf :: Fold a a' b b' -> a -> Bool+nullOf l = LF.nullOf l++infixr 8 ^..++-- | Returns a list of all of the referenced values in order.+(^..) :: a -> Fold a a' b b' -> [b]+x^..l = x LF.^.. l++infixr 8 ^?++-- | Returns 'Just' the first referenced value.+-- Returns 'Nothing' if there are no referenced values.+(^?) :: a -> Fold a a' b b' -> Maybe b+x^?l = x LF.^? l
src/Lens/Family2/State/Lazy.hs view
@@ -1,73 +1,122 @@ {-# LANGUAGE Rank2Types #-} -- | Lenses allow you to use fields of the state of a state monad as if they were variables in an imperative language.--- 'access' is used to retrieve the value of a variable, and '~=' and '%=' allow you to set and modify a variable.+-- 'use' is used to retrieve the value of a variable, and '.=' and '%=' allow you to set and modify a variable. -- C-style compound assignments are also provided. module Lens.Family2.State.Lazy-  ( focus-  , access+  ( LFS.zoom+  , use, uses   , (%=)-  , (~=)+  , assign, (.=)   , (%%=)-  -- * Compound Assignments+-- * Compound Assignments   , (+=), (-=), (*=)   , (//=)   , (&&=), (||=)   , (<>=)+-- * Types+  , LFS.Zooming+-- * Re-exports+  , LensLike, LensLike'+  , FoldLike+  , Setter, Setter'+  , LFS.StateT, MonadState, Writer+  , Monoid   ) where  import Data.Monoid (Monoid, mappend)+import Data.Tuple (swap) import Control.Monad (liftM)-import Control.Monad.State.Lazy (MonadState, StateT(..), get, modify, state)-import Lens.Family (Getter, Setter, (^.), (%~))+import Control.Monad.Trans.Writer.Lazy (Writer, writer, runWriter)+import Control.Monad.State.Lazy (MonadState, get, modify, state)+import Lens.Family2 ( LensLike, LensLike'+                    , FoldLike+                    , Setter, Setter'+                    , view, views, (%~)+                    ) import qualified Lens.Family.State.Lazy as LFS-import Lens.Family2.Stock (Lens) --- | Lift a stateful operation on a field to a stateful operation on the whole state.--- This is a good way to call a \"subroutine\" that only needs access to part of the state.-focus :: Monad m => Lens a b -> StateT b m c -> StateT a m c-focus l = LFS.focus l+use :: MonadState a m => FoldLike b a a' b b' -> m b+-- ^ @+-- use :: MonadState a m => Getter a a' b b' -> m b+-- @+--+-- Retrieve a field of the state+--+-- @+-- use :: (Monoid b, MonadState a m) => Fold a a' b b' -> m b+-- @+--+-- Retrieve a monoidal summary of all the referenced fields from the state+use l = view l `liftM` get --- | Retrieve a field of the state-access :: MonadState a m => Getter a b -> m b-access l = (^. l) `liftM` get+uses :: MonadState a m => FoldLike r a a' b b' -> (b -> r) -> m r+-- ^ @+-- uses :: (MonadState a m, Monoid r) => Fold a a' b b' -> (b -> r) -> m r+-- @+--+-- Retrieve all the referenced fields from the state and foldMap the results together with @f :: b -> r@.+--+-- @+-- uses :: MonadState a m => Getter a a' b b' -> (b -> r) -> m r+-- @+--+-- Retrieve a field of the state and pass it through the function @f :: b -> r@.+--+-- @uses l f = f <$> use l@+uses l f = views l f `liftM` get  infix 4 %= --- | Modify a field of the state-(%=) :: MonadState a m => Setter a b -> (b -> b) -> m ()+-- | Modify a field of the state.+(%=) :: MonadState a m => Setter a a b b' -> (b -> b') -> m () l %= f = modify (l %~ f) -infix 4 ~=+infix 4 .= --- | Set a field of the state-(~=) :: MonadState a m => Setter a b -> b -> m ()-l ~= v = l %= const v+-- | Set a field of the state.+(.=) :: MonadState a m => Setter a a b b' -> b' -> m ()+l .= v = l %= const v +-- | Set a field of the state.+assign :: MonadState a m => Setter a a b b' -> b' -> m ()+assign = (.=)+ infix 4 %%= --- | Modify a field of the state while returning another value-(%%=) :: MonadState a m => Lens a b -> (b -> (c, b)) -> m c-l %%= f = state (l f)+(%%=) :: MonadState a m => LensLike (Writer c) a a b b' -> (b -> (c, b')) -> m c+-- ^ @+-- (%%=) :: MonadState a m => Lens a a b b' -> (b -> (c, b')) -> m c+-- @+--+-- Modify a field of the state while returning another value.+--+-- @+-- (%%=) :: (MonadState a m, Monoid c) => Traversal a a b b' -> (b -> (c, b')) -> m c+-- @+--+-- Modify each field of the state and return the 'mconcat' of the other values.+l %%= f = state (swap . runWriter . l (writer . swap . f))  infixr 4 +=, -=, *= -(+=), (-=), (*=) :: (MonadState a m, Num b) => Setter a b -> b -> m ()+(+=), (-=), (*=) :: (MonadState a m, Num b) => Setter' a b -> b -> m () f += b = f %= (+ b) f -= b = f %= subtract b f *= b = f %= (* b)  infixr 4 //= -(//=) :: (MonadState a m, Fractional b) => Setter a b -> b -> m ()+(//=) :: (MonadState a m, Fractional b) => Setter' a b -> b -> m () f //= b = f %= (/ b)  infixr 4 &&=, ||= -(&&=), (||=) :: MonadState a m => Setter a Bool -> Bool -> m ()+(&&=), (||=) :: MonadState a m => Setter' a Bool -> Bool -> m () f &&= b = f %= (&& b) f ||= b = f %= (|| b)  infixr 4 <>= -(<>=) :: (Monoid o, MonadState a m) => Setter a o -> o -> m ()+-- | Monoidally append a value to all referenced fields of the state.+(<>=) :: (Monoid o, MonadState a m) => Setter' a o -> o -> m () f <>= b = f %= (`mappend` b)
src/Lens/Family2/State/Strict.hs view
@@ -1,73 +1,122 @@ {-# LANGUAGE Rank2Types #-} -- | Lenses allow you to use fields of the state of a state monad as if they were variables in an imperative language.--- 'access' is used to retrieve the value of a variable, and '~=' and '%=' allow you to set and modify a variable.+-- 'use' is used to retrieve the value of a variable, and '.=' and '%=' allow you to set and modify a variable. -- C-style compound assignments are also provided. module Lens.Family2.State.Strict-  ( focus-  , access+  ( LFS.zoom+  , use, uses   , (%=)-  , (~=)+  , assign, (.=)   , (%%=)-  -- * Compound Assignments+-- * Compound Assignments   , (+=), (-=), (*=)   , (//=)   , (&&=), (||=)   , (<>=)+-- * Types+  , LFS.Zooming+-- * Re-exports+  , LensLike, LensLike'+  , FoldLike+  , Setter, Setter'+  , LFS.StateT, MonadState, Writer+  , Monoid   ) where  import Data.Monoid (Monoid, mappend)+import Data.Tuple (swap) import Control.Monad (liftM)-import Control.Monad.State.Strict (MonadState, StateT(..), get, modify, state)-import Lens.Family (Getter, Setter, (^.), (%~))+import Control.Monad.Trans.Writer.Lazy (Writer, writer, runWriter)+import Control.Monad.State.Strict (MonadState, get, modify, state)+import Lens.Family2 ( LensLike, LensLike'+                    , FoldLike+                    , Setter, Setter'+                    , view, views, (%~)+                    ) import qualified Lens.Family.State.Strict as LFS-import Lens.Family2.Stock (Lens) --- | Lift a stateful operation on a field to a stateful operation on the whole state.--- This is a good way to call a \"subroutine\" that only needs access to part of the state.-focus :: Monad m => Lens a b -> StateT b m c -> StateT a m c-focus l = LFS.focus l+use :: MonadState a m => FoldLike b a a' b b' -> m b+-- ^ @+-- use :: MonadState a m => Getter a a' b b' -> m b+-- @+--+-- Retrieve a field of the state+--+-- @+-- use :: (Monoid b, MonadState a m) => Fold a a' b b' -> m b+-- @+--+-- Retrieve a monoidal summary of all the referenced fields from the state+use l = view l `liftM` get --- | Retrieve a field of the state-access :: MonadState a m => Getter a b -> m b-access l = (^. l) `liftM` get+uses :: MonadState a m => FoldLike r a a' b b' -> (b -> r) -> m r+-- ^ @+-- uses :: (MonadState a m, Monoid r) => Fold a a' b b' -> (b -> r) -> m r+-- @+--+-- Retrieve all the referenced fields from the state and foldMap the results together with @f :: b -> r@.+--+-- @+-- uses :: MonadState a m => Getter a a' b b' -> (b -> r) -> m r+-- @+--+-- Retrieve a field of the state and pass it through the function @f :: b -> r@.+--+-- @uses l f = f <$> use l@+uses l f = views l f `liftM` get  infix 4 %= --- | Modify a field of the state-(%=) :: MonadState a m => Setter a b -> (b -> b) -> m ()+-- | Modify a field of the state.+(%=) :: MonadState a m => Setter a a b b' -> (b -> b') -> m () l %= f = modify (l %~ f) -infix 4 ~=+infix 4 .= --- | Set a field of the state-(~=) :: MonadState a m => Setter a b -> b -> m ()-l ~= v = l %= const v+-- | Set a field of the state.+(.=) :: MonadState a m => Setter a a b b' -> b' -> m ()+l .= v = l %= const v +-- | Set a field of the state.+assign :: MonadState a m => Setter a a b b' -> b' -> m ()+assign = (.=)+ infix 4 %%= --- | Modify a field of the state while returning another value-(%%=) :: MonadState a m => Lens a b -> (b -> (c, b)) -> m c-l %%= f = state (l f)+(%%=) :: MonadState a m => LensLike (Writer c) a a b b' -> (b -> (c, b')) -> m c+-- ^ @+-- (%%=) :: MonadState a m => Lens a a b b' -> (b -> (c, b')) -> m c+-- @+--+-- Modify a field of the state while returning another value.+--+-- @+-- (%%=) :: (MonadState a m, Monoid c) => Traversal a a b b' -> (b -> (c, b')) -> m c+-- @+--+-- Modify each field of the state and return the 'mconcat' of the other values.+l %%= f = state (swap . runWriter . l (writer . swap . f))  infixr 4 +=, -=, *= -(+=), (-=), (*=) :: (MonadState a m, Num b) => Setter a b -> b -> m ()+(+=), (-=), (*=) :: (MonadState a m, Num b) => Setter' a b -> b -> m () f += b = f %= (+ b) f -= b = f %= subtract b f *= b = f %= (* b)  infixr 4 //= -(//=) :: (MonadState a m, Fractional b) => Setter a b -> b -> m ()+(//=) :: (MonadState a m, Fractional b) => Setter' a b -> b -> m () f //= b = f %= (/ b)  infixr 4 &&=, ||= -(&&=), (||=) :: MonadState a m => Setter a Bool -> Bool -> m ()+(&&=), (||=) :: MonadState a m => Setter' a Bool -> Bool -> m () f &&= b = f %= (&& b) f ||= b = f %= (|| b)  infixr 4 <>= -(<>=) :: (Monoid o, MonadState a m) => Setter a o -> o -> m ()+-- | Monoidally append a value to all referenced fields of the state.+(<>=) :: (Monoid o, MonadState a m) => Setter' a o -> o -> m () f <>= b = f %= (`mappend` b)
src/Lens/Family2/Stock.hs view
@@ -1,56 +1,91 @@ {-# LANGUAGE Rank2Types #-}--- | This module contains lenses for common structures in Haskell.--- It also contains the lens combinators 'mergeL' and '***'.-module Lens.Family2.Stock-  ( -- * Lens Combinators-    Stock.mergeL-  , (***)-  -- * Stock Lenses-  , fstL, sndL-  , funL-  , mapL, intMapL-  , setL, intSetL-  -- * Types-  , LensFamily, Lens+-- | This module contains lenses and traversals for common structures in Haskell.+-- It also contains the combinators for lenses and traversals.+module Lens.Family2.Stock (+-- * Lens Combinators+    Stock.choosing+  , Stock.alongside+  , Stock.beside+-- * Stock Lenses+  , _1, _2, both+  , chosen+  , ix+  , at, intAt+  , contains, intContains+-- * Stock Traversals+  , _Left, _Right+  , _Just, _Nothing+  , ignored+-- * Types+  , Stock.AlongsideLeft, Stock.AlongsideRight+-- * Re-exports+  , Lens, Lens'+  , Traversal, Traversal'+  , Stock.LensLike, Stock.LensLike'+  , Stock.Applicative   ) where -import Lens.Family2.Unchecked (LensFamily, Lens) import qualified Lens.Family.Stock as Stock-import Lens.Family ((^.), (<~))+import Lens.Family2 ( Lens, Lens'+                    , Traversal, Traversal'+                    ) import qualified Data.Map as Map import qualified Data.IntMap as IntMap import qualified Data.Set as Set import qualified Data.IntSet as IntSet --- I suspect there is a more clever way to define this function.--- | Given two lens families, make a new lens on their product.-(***) :: LensFamily a1 a1' b1 b1' -> LensFamily a2 a2' b2 b2' -> LensFamily (a1, a2) (a1', a2') (b1, b2) (b1', b2')-(***) l1 l2 f (a1, a2) = (\(v'1, v'2) -> (l1 <~ v'1 $ a1, l2 <~ v'2 $ a2)) `fmap` f (a1 ^. l1, a2 ^. l2)- -- | Lens on the first element of a pair.-fstL :: LensFamily (a, b) (a', b) a a'-fstL = Stock.fstL+_1 :: Lens (a, b) (a', b) a a'+_1 = Stock._1  -- | Lens on the second element of a pair.-sndL :: LensFamily (a, b) (a, b') b b'-sndL = Stock.sndL+_2 :: Lens (a, b) (a, b') b b'+_2 = Stock._2 +-- | Lens on the Left or Right element of an ('Either' a a).+chosen :: Lens (Either a a) (Either b b) a b+chosen = Stock.chosen+ -- | Lens on a given point of a function.-funL :: (Eq k) => k -> Lens (k -> v) v-funL = Stock.funL+ix :: (Eq k) => k -> Lens' (k -> v) v+ix = Stock.ix  -- | Lens on a given point of a 'Map.Map'.-mapL :: (Ord k) => k -> Lens (Map.Map k v) (Maybe v)-mapL = Stock.mapL+at :: (Ord k) => k -> Lens' (Map.Map k v) (Maybe v)+at = Stock.at  -- | Lens on a given point of a 'IntMap.IntMap'.-intMapL :: Int -> Lens (IntMap.IntMap v) (Maybe v)-intMapL = Stock.intMapL+intAt :: Int -> Lens' (IntMap.IntMap v) (Maybe v)+intAt = Stock.intAt  -- | Lens on a given point of a 'Set.Set'.-setL :: (Ord k) => k -> Lens (Set.Set k) Bool-setL = Stock.setL+contains :: (Ord k) => k -> Lens' (Set.Set k) Bool+contains = Stock.contains  -- | Lens on a given point of a 'IntSet.IntSet'.-intSetL :: Int -> Lens IntSet.IntSet Bool-intSetL = Stock.intSetL+intContains :: Int -> Lens' IntSet.IntSet Bool+intContains = Stock.intContains++-- | Traversal on the 'Left' element of an 'Either'.+_Left :: Traversal (Either a b) (Either a' b) a a'+_Left = Stock._Left++-- | Traversal on the 'Right' element of an 'Either'.+_Right :: Traversal (Either a b) (Either a b') b b'+_Right = Stock._Right++-- | Traversal on the 'Just' element of a 'Maybe'.+_Just :: Traversal (Maybe a) (Maybe a') a a'+_Just = Stock._Just++-- | Traversal on the 'Nothing' element of a 'Maybe'.+_Nothing :: Traversal' (Maybe a) ()+_Nothing = Stock._Nothing++-- | Traversals on both elements of a pair @(a,a)@.+both :: Traversal (a,a) (b,b) a b+both = Stock.both++-- | The empty traveral on any type.+ignored :: Traversal a a b b'+ignored = Stock.ignored
src/Lens/Family2/Unchecked.hs view
@@ -1,22 +1,23 @@ {-# LANGUAGE Rank2Types #-} -- | /Caution/: Improper use of this module can lead to unexpected behaviour if the preconditions of the functions are not met.--- --- A lens family is created by separating a substructure from the rest of its structure by a functor.+module Lens.Family2.Unchecked (+-- * Lenses+-- | A lens family is created by separating a substructure from the rest of its structure by a functor. -- How to create a lens family is best illustrated by the common example of a field of a record: -- -- > data MyRecord a = MyRecord { _myA :: a, _myB :: Int } -- > -- > -- The use of type variables a and a' allow for polymorphic updates.--- > myA :: LensFamily (MyRecord a) (MyRecord a') a a'+-- > myA :: Lens (MyRecord a) (MyRecord a') a a' -- > myA f (MyRecord a b) = (\a' -> MyRecord a' b) `fmap` (f a) -- >--- > -- The field _myB is monomorphic, so we can use a plain Lens type.--- > -- However, the structure of the function is exactly the same as for LensFamily.--- > myB :: Lens (MyRecord a) Int+-- > -- The field _myB is monomorphic, so we can use a 'Lens'' type.+-- > -- However, the structure of the function is exactly the same as for Lens.+-- > myB :: Lens' (MyRecord a) Int -- > myB f (MyRecord a b) = (\b' -> MyRecord a b') `fmap` (f b) -- -- By following this template you can safely build your own lenses.--- To use this template, you do not need anything from this module other than the type synonyms 'LensFamily' and 'Lens', and even they are optional.+-- To use this template, you do not need anything from this module other than the type synonyms 'Lens' and 'Lens'', and even they are optional. -- See the @lens-family-th@ package to generate this code using Template Haskell. -- -- /Note/: It is possible to build lenses without even depending on @lens-family@ by expanding away the type synonym.@@ -26,33 +27,76 @@ -- > myA f (MyRecord a b) = (\a' -> MyRecord a' b) `fmap` (f a) -- -- You can build lenses for more than just fields of records.--- Any value @lens :: LensFamily a a' b b'@ is well-defined when it satisfies the two van Laarhoven lens laws:+-- Any value @l :: Lens a a' b b'@ is well-defined when it satisfies the two van Laarhoven lens laws: ----- * @lens Identity === Identity@+-- * @l Identity === Identity@ ----- * @--- lens (composeCoalgebroid f g) === composeCoalgebroid (lens f) (lens g)---  where---   composeCoalgebroid :: (Functor f, Functor g) => (b -> f c) -> (a -> g b) -> a -> (Compose g f) c---   composeCoalgebroid f g a = Compose $ f \`fmap\` g a === id--- @+-- * @l (Compose . fmap f . g) === Compose . fmap (l f) . (l g)@ ----- The functions 'mkLens' and 'mkIsoLens' can also be used to construct lenses.+-- The functions 'lens' and 'iso' can also be used to construct lenses. -- The resulting lenses will be well-defined so long as their preconditions are satisfied.-module Lens.Family2.Unchecked-  ( mkLens-  , mkIsoLens-  , LF.Setting, LF.setting-  -- * Types-  , LensFamily, Lens-  , LF.SetterFamily, LF.Setter++-- * Traversals+--+-- | If you have zero or more fields of the same type of a record, a traversal can be used to refer to all of them in order.+-- Multiple references are made by replacing the 'Functor' constraint of lenses with an 'Control.Applicative.Applicative' constraint.+-- Consider the following example of a record with two 'Int' fields.+--+-- > data MyRecord = MyRecord { _myA :: Int, _myB :: Int }+-- >+-- > -- myInts is a traversal over both fields of MyRecord.+-- > myInts :: Traversal' MyRecord Int+-- > myInts f (MyRecord a b) = MyRecord <$> f a <*> f b+--+-- If the record and the referenced fields are parametric, you can can build traversals with polymorphic updating.+-- Consider the following example of a record with two 'Maybe' fields.+--+-- > data MyRecord a = MyRecord { _myA :: Maybe a, _myB :: Maybe a }+-- >+-- > -- myInts is a traversal over both fields of MyRecord.+-- > myMaybes :: Traversal (MyRecord a) (MyRecord a') (Maybe a) (Maybe a')+-- > myMaybes f (MyRecord a b) = MyRecord <$> f a <*> f b+--+-- /Note/: As with lenses, is possible to build traversals without even depending on @lens-family-core@ by expanding away the type synonym.+--+-- > -- A traversal definition that only requires the Haskell "Prelude".+-- > myMaybes :: Applicative f => (Maybe a -> f (Maybe a')) -> MyRecord a -> f (MyRecord a')+-- > myMaybes f (MyRecord a b) = MyRecord <$> f a <*> f b+--+-- Unfortuantely, there are no helper functions for making traversals.+-- You must make them by hand.+--+-- Any value @t :: Traversal a a' b b'@ is well-defined when it satisfies the two van Laarhoven traversal laws:+--+-- * @t Identity === Identity@+--+-- * @t (Compose . fmap f . g) === Compose . fmap (t f) . (t g)@+--+-- 'Data.Traversable.traverse' is the canonical traversal for various containers.++-- * Documentation+    lens+  , iso+  , LF.setting+-- * Types+  , Lens, Lens'+  , Traversal, Traversal'+  , LF.Setting+  , LF.LensLike, LF.LensLike'+  , LF.Setter, LF.Setter'+-- * Re-exports+  , Applicative   ) where +import Control.Applicative (Applicative) import qualified Lens.Family.Unchecked as LF -type LensFamily a a' b b' = forall f. Functor f => LF.RefFamily f a a' b b'-type Lens a b = LensFamily a a b b+type Lens a a' b b' = forall f. Functor f => LF.LensLike f a a' b b'+type Lens' a b = Lens a a b b +type Traversal a a' b b' = forall f. Applicative f => LF.LensLike f a a' b b'+type Traversal' a b = Traversal a a b b+ -- | Build a lens from a @getter@ and @setter@ families. -- -- /Caution/: In order for the generated lens family to be well-defined, you must ensure that the three lens laws hold:@@ -62,10 +106,10 @@ -- * @setter a (getter a) === a@ -- -- * @setter (setter a b1) b2) === setter a b2@-mkLens :: (a -> b) -- ^ getter-       -> (a -> b' -> a') -- ^ setter-       -> LensFamily a a' b b'-mkLens = LF.mkLens+lens :: (a -> b) -- ^ getter+     -> (a -> b' -> a') -- ^ setter+     -> Lens a a' b b'+lens = LF.lens  -- | Build a lens from isomorphism families. --@@ -74,7 +118,7 @@ -- * @yin . yang === id@ -- -- * @yang . yin === id@-mkIsoLens :: (a -> b) -- ^ yin-          -> (b' -> a') -- ^ yang-          -> LensFamily a a' b b'-mkIsoLens = LF.mkIsoLens+iso :: (a -> b) -- ^ yin+    -> (b' -> a') -- ^ yang+    -> Lens a a' b b'+iso = LF.iso