{-# LANGUAGE Rank2Types #-} -- | Lenses allow you to use fields of the state of a state monad as if they were variables in an imperative language. -- '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 ( LFS.zoom , use, uses , (%=) , assign, (.=) , (%%=) -- * 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.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 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 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 a b b' -> (b -> b') -> m () l %= f = modify (l %~ f) infix 4 .= -- | 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 %%= (%%=) :: 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 () 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 () f //= b = f %= (/ b) infixr 4 &&=, ||= (&&=), (||=) :: MonadState a m => Setter' a Bool -> Bool -> m () f &&= b = f %= (&& b) f ||= b = f %= (|| b) infixr 4 <>= -- | 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)