    -- | 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.Family.State.Strict
      ( zoom
      , use, uses
      , (%=)
      , assign, (.=)
      , (%%=)
      , (<~)
    -- * Compound Assignments
      , (+=), (-=), (*=)
      , (//=)
      , (&&=), (||=)
      , (<>=)
    -- * Strict Assignments
      , (%!=)
      , (+!=), (-!=), (*!=)
      , (//!=)
      , (&&!=), (||!=)
      , (<>!=)
    -- * Types
      , Zooming
    -- * Re-exports
      , LensLike, LensLike'
      , FoldLike, Constant
      , ASetter, ASetter', Identity
      , StateT, Writer
      ) where

    import Control.Monad (liftM)
    import Control.Monad.Trans.State.Strict (StateT(..), state, get, modify, modify')
    import Control.Monad.Trans.Writer.Lazy (Writer, writer, runWriter)
    import Data.Tuple (swap)
    import Lens.Family
    import Lens.Family.State.Zoom

    {- all these Monad constraints could be weakened to Functor or Applicative constraints -}

    zoom :: Monad m => LensLike' (Zooming m c) s a -> StateT a m c -> StateT s m c
    -- ^ @
    -- zoom :: Monad m => Lens' s a -> StateT a m c -> StateT s m c
    -- @
    --
    -- 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.
    --
    -- @
    -- zoom :: (Monad m, Monoid c) => Traversal' s a -> StateT a m c -> StateT s m c
    -- @
    --
    -- Run the \"subroutine\" on each element of the traversal in turn and 'mconcat' all the results together.
    --
    -- @
    -- zoom :: Monad m => Traversal' s a -> StateT a m () -> StateT s m ()
    -- @
    --
    -- Run the \"subroutine\" on each element the traversal in turn.
    zoom :: forall (m :: * -> *) c s a.
    Monad m =>
    LensLike' (Zooming m c) s a -> StateT a m c -> StateT s m c
    zoom LensLike' (Zooming m c) s a
    l StateT a m c
    m = (s -> m (c, s)) -> StateT s m c
    forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
    StateT ((s -> m (c, s)) -> StateT s m c)
    -> (s -> m (c, s)) -> StateT s m c
    forall a b. (a -> b) -> a -> b
    $ Zooming m c s -> m (c, s)
    forall (m :: * -> *) c a. Zooming m c a -> m (c, a)
    unZooming (Zooming m c s -> m (c, s))
    -> (s -> Zooming m c s) -> s -> m (c, s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LensLike' (Zooming m c) s a
    l (m (c, a) -> Zooming m c a
    forall (m :: * -> *) c a. m (c, a) -> Zooming m c a
    Zooming (m (c, a) -> Zooming m c a)
    -> (a -> m (c, a)) -> a -> Zooming m c a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (StateT a m c -> a -> m (c, a)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    runStateT StateT a m c
    m))

    use :: Monad m => FoldLike a s t a b -> StateT s m a
    -- ^ @
    -- use :: Monad m => Getter s t a b -> StateT s m a
    -- @
    --
    -- Retrieve a field of the state
    --
    -- @
    -- use :: (Monad m, Monoid a) => Fold s t a b -> StateT s m a
    -- @
    --
    -- Retrieve a monoidal summary of all the referenced fields from the state
    use :: forall (m :: * -> *) a s t b.
    Monad m =>
    FoldLike a s t a b -> StateT s m a
    use FoldLike a s t a b
    l = FoldLike a s t a b -> s -> a
    forall a s t b. FoldLike a s t a b -> s -> a
    view FoldLike a s t a b
    l (s -> a) -> StateT s m s -> StateT s m a
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    `liftM` StateT s m s
    forall (m :: * -> *) s. Monad m => StateT s m s
    get

    uses :: Monad m => FoldLike r s t a b -> (a -> r) -> StateT s m r
    -- ^ @
    -- uses :: (Monad m, Monoid r) => Fold s t a b -> (a -> r) -> StateT s m r
    -- @
    --
    -- Retrieve all the referenced fields from the state and foldMap the results together with @f :: a -> r@.
    --
    -- @
    -- uses :: Monad m => Getter s t a b -> (a -> r) -> StateT s m r
    -- @
    --
    -- Retrieve a field of the state and pass it through the function @f :: a -> r@.
    --
    -- @uses l f = f \<$> use l@
    uses :: forall (m :: * -> *) r s t a b.
    Monad m =>
    FoldLike r s t a b -> (a -> r) -> StateT s m r
    uses FoldLike r s t a b
    l a -> r
    f = FoldLike r s t a b -> (a -> r) -> s -> r
    forall r s t a b. FoldLike r s t a b -> (a -> r) -> s -> r
    views FoldLike r s t a b
    l a -> r
    f (s -> r) -> StateT s m s -> StateT s m r
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    `liftM` StateT s m s
    forall (m :: * -> *) s. Monad m => StateT s m s
    get

    infix 4 %=

    -- | Modify a field of the state.
    (%=) :: Monad m => ASetter s s a b -> (a -> b) -> StateT s m ()
    ASetter s s a b
    l %= :: forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= a -> b
    f = (s -> s) -> StateT s m ()
    forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
    modify (ASetter s s a b
    l ASetter s s a b -> (a -> b) -> s -> s
    forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
    %~ a -> b
    f)

    infix 4 .=

    -- | Set a field of the state.
    (.=) :: Monad m => ASetter s s a b -> b -> StateT s m ()
    ASetter s s a b
    l .= :: forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> b -> StateT s m ()
    .= b
    v = ASetter s s a b
    l ASetter s s a b -> (a -> b) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= b -> a -> b
    forall a b. a -> b -> a
    const b
    v

    -- | Set a field of the state.
    assign :: Monad m => ASetter s s a b -> b -> StateT s m ()
    assign :: forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> b -> StateT s m ()
    assign = ASetter s s a b -> b -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> b -> StateT s m ()
    (.=)

    infixr 2 <~

    -- | Set a field of the state using the result of executing a stateful command.
    (<~) :: Monad m => ASetter s s a b -> StateT s m b -> StateT s m ()
    ASetter s s a b
    l <~ :: forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> StateT s m b -> StateT s m ()
    <~ StateT s m b
    v = ASetter s s a b -> b -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> b -> StateT s m ()
    assign ASetter s s a b
    l (b -> StateT s m ()) -> StateT s m b -> StateT s m ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< StateT s m b
    v

    infix 4 %%=

    (%%=) :: Monad m => LensLike (Writer c) s s a b -> (a -> (c, b)) -> StateT s m c
    -- ^ @
    -- (%%=) :: Monad m => Lens s s a b -> (a -> (c, b)) -> StateT s m c
    -- @
    --
    -- Modify a field of the state while returning another value.
    --
    -- @
    -- (%%=) :: (Monad m, Monoid c) => Traversal s s a b -> (a -> (c, b)) -> StateT s m c
    -- @
    --
    -- Modify each field of the state and return the 'mconcat' of the other values.
    LensLike (Writer c) s s a b
    l %%= :: forall (m :: * -> *) c s a b.
    Monad m =>
    LensLike (Writer c) s s a b -> (a -> (c, b)) -> StateT s m c
    %%= a -> (c, b)
    f = (s -> (c, s)) -> StateT s m c
    forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
    state ((s, c) -> (c, s)
    forall a b. (a, b) -> (b, a)
    swap ((s, c) -> (c, s)) -> (s -> (s, c)) -> s -> (c, s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Writer c s -> (s, c)
    forall w a. Writer w a -> (a, w)
    runWriter (Writer c s -> (s, c)) -> (s -> Writer c s) -> s -> (s, c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LensLike (Writer c) s s a b
    l ((b, c) -> WriterT c Identity b
    forall (m :: * -> *) a w. Monad m => (a, w) -> WriterT w m a
    writer ((b, c) -> WriterT c Identity b)
    -> (a -> (b, c)) -> a -> WriterT c Identity b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (c, b) -> (b, c)
    forall a b. (a, b) -> (b, a)
    swap ((c, b) -> (b, c)) -> (a -> (c, b)) -> a -> (b, c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> (c, b)
    f))

    infixr 4 +=, -=, *=

    (+=), (-=), (*=) :: (Monad m, Num a) => ASetter' s a -> a -> StateT s m ()
    ASetter' s a
    l += :: forall (m :: * -> *) a s.
    (Monad m, Num a) =>
    ASetter' s a -> a -> StateT s m ()
    += a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= (a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    a)
    ASetter' s a
    l -= :: forall (m :: * -> *) a s.
    (Monad m, Num a) =>
    ASetter' s a -> a -> StateT s m ()
    -= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= a -> a -> a
    forall a. Num a => a -> a -> a
    subtract a
    a
    ASetter' s a
    l *= :: forall (m :: * -> *) a s.
    (Monad m, Num a) =>
    ASetter' s a -> a -> StateT s m ()
    *= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= (a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    a)

    infixr 4 //=

    (//=) :: (Monad m, Fractional a) => ASetter' s a -> a -> StateT s m ()
    ASetter' s a
    l //= :: forall (m :: * -> *) a s.
    (Monad m, Fractional a) =>
    ASetter' s a -> a -> StateT s m ()
    //= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= (a -> a -> a
    forall a. Fractional a => a -> a -> a
    / a
    a)

    infixr 4 &&=, ||=

    (&&=), (||=) :: Monad m => ASetter' s Bool -> Bool -> StateT s m ()
    ASetter' s Bool
    l &&= :: forall (m :: * -> *) s.
    Monad m =>
    ASetter' s Bool -> Bool -> StateT s m ()
    &&= Bool
    a = ASetter' s Bool
    l ASetter' s Bool -> (Bool -> Bool) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= (Bool -> Bool -> Bool
    && Bool
    a)
    ASetter' s Bool
    l ||= :: forall (m :: * -> *) s.
    Monad m =>
    ASetter' s Bool -> Bool -> StateT s m ()
    ||= Bool
    a = ASetter' s Bool
    l ASetter' s Bool -> (Bool -> Bool) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= (Bool -> Bool -> Bool
    || Bool
    a)

    infixr 4 <>=

    -- | Monoidally append a value to all referenced fields of the state.
    (<>=) :: (Monad m, Monoid a) => ASetter' s a -> a -> StateT s m ()
    ASetter' s a
    l <>= :: forall (m :: * -> *) a s.
    (Monad m, Monoid a) =>
    ASetter' s a -> a -> StateT s m ()
    <>= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %= (a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    a)

    infix 4 %!=

    -- | Strictly modify a field of the state.
    (%!=) :: Monad m => ASetter s s a b -> (a -> b) -> StateT s m ()
    ASetter s s a b
    l %!= :: forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= a -> b
    f = (s -> s) -> StateT s m ()
    forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
    modify' (ASetter s s a b
    l ASetter s s a b -> (a -> b) -> s -> s
    forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
    %~ a -> b
    f)

    infixr 4 +!=, -!=, *!=

    (+!=), (-!=), (*!=) :: (Monad m, Num a) => ASetter' s a -> a -> StateT s m ()
    ASetter' s a
    l +!= :: forall (m :: * -> *) a s.
    (Monad m, Num a) =>
    ASetter' s a -> a -> StateT s m ()
    +!= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= (a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    a)
    ASetter' s a
    l -!= :: forall (m :: * -> *) a s.
    (Monad m, Num a) =>
    ASetter' s a -> a -> StateT s m ()
    -!= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= a -> a -> a
    forall a. Num a => a -> a -> a
    subtract a
    a
    ASetter' s a
    l *!= :: forall (m :: * -> *) a s.
    (Monad m, Num a) =>
    ASetter' s a -> a -> StateT s m ()
    *!= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= (a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    a)

    infixr 4 //!=

    (//!=) :: (Monad m, Fractional a) => ASetter' s a -> a -> StateT s m ()
    ASetter' s a
    l //!= :: forall (m :: * -> *) a s.
    (Monad m, Fractional a) =>
    ASetter' s a -> a -> StateT s m ()
    //!= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= (a -> a -> a
    forall a. Fractional a => a -> a -> a
    / a
    a)

    infixr 4 &&!=, ||!=

    (&&!=), (||!=) :: Monad m => ASetter' s Bool -> Bool -> StateT s m ()
    ASetter' s Bool
    l &&!= :: forall (m :: * -> *) s.
    Monad m =>
    ASetter' s Bool -> Bool -> StateT s m ()
    &&!= Bool
    a = ASetter' s Bool
    l ASetter' s Bool -> (Bool -> Bool) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= (Bool -> Bool -> Bool
    && Bool
    a)
    ASetter' s Bool
    l ||!= :: forall (m :: * -> *) s.
    Monad m =>
    ASetter' s Bool -> Bool -> StateT s m ()
    ||!= Bool
    a = ASetter' s Bool
    l ASetter' s Bool -> (Bool -> Bool) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= (Bool -> Bool -> Bool
    || Bool
    a)

    infixr 4 <>!=

    (<>!=) :: (Monad m, Monoid a) => ASetter' s a -> a -> StateT s m ()
    ASetter' s a
    l <>!= :: forall (m :: * -> *) a s.
    (Monad m, Monoid a) =>
    ASetter' s a -> a -> StateT s m ()
    <>!= a
    a = ASetter' s a
    l ASetter' s a -> (a -> a) -> StateT s m ()
    forall (m :: * -> *) s a b.
    Monad m =>
    ASetter s s a b -> (a -> b) -> StateT s m ()
    %!= (a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    a)