{-# LANGUAGE CPP #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
#ifdef TRUSTWORTHY
{-# LANGUAGE Trustworthy #-}
#endif
#ifndef MIN_VERSION_mtl
#define MIN_VERSION_mtl(x,y,z) 1
#endif
module Control.Lens.Lens
(
Lens, Lens'
, IndexedLens, IndexedLens'
, ALens, ALens'
, AnIndexedLens, AnIndexedLens'
, lens, ilens, iplens
, (%%~), (%%=)
, (%%@~), (%%@=)
, (<%@~), (<%@=)
, (<<%@~), (<<%@=)
, (&), (<&>), (??)
, (&~)
, choosing
, chosen
, alongside
, inside
, (<%~), (<+~), (<-~), (<*~), (<//~)
, (<^~), (<^^~), (<**~)
, (<||~), (<&&~), (<<>~)
, (<<%~), (<<.~), (<<+~), (<<-~), (<<*~)
, (<<//~), (<<^~), (<<^^~), (<<**~)
, (<<||~), (<<&&~), (<<<>~)
, (<%=), (<+=), (<-=), (<*=), (<//=)
, (<^=), (<^^=), (<**=)
, (<||=), (<&&=), (<<>=)
, (<<%=), (<<.=), (<<+=), (<<-=), (<<*=)
, (<<//=), (<<^=), (<<^^=), (<<**=)
, (<<||=), (<<&&=), (<<<>=)
, (<<~)
, cloneLens
, cloneIndexPreservingLens
, cloneIndexedLens
, overA
, storing
, (^#)
, ( #~ ), ( #%~ ), ( #%%~ ), (<#~), (<#%~)
, ( #= ), ( #%= ), ( #%%= ), (<#=), (<#%=)
, devoid
, united
, Context(..)
, Context'
, locus
) where
import Control.Applicative
import Control.Arrow
import Control.Comonad
import Control.Lens.Internal.Context
import Control.Lens.Internal.Getter
import Control.Lens.Internal.Indexed
import Control.Lens.Type
import Control.Monad.State as State
import Data.Monoid
import Data.Profunctor
import Data.Profunctor.Rep
import Data.Profunctor.Unsafe
import Data.Void
#ifdef HLINT
{-# ANN module "HLint: ignore Use ***" #-}
#endif
infixl 8 ^#
infixr 4 %%@~, <%@~, <<%@~, %%~, <+~, <*~, <-~, <//~, <^~, <^^~, <**~, <&&~, <||~, <<>~, <%~, <<%~, <<.~, <#~, #~, #%~, <#%~, #%%~
infix 4 %%@=, <%@=, <<%@=, %%=, <+=, <*=, <-=, <//=, <^=, <^^=, <**=, <&&=, <||=, <<>=, <%=, <<%=, <<.=, <#=, #=, #%=, <#%=, #%%=
infixr 2 <<~
infixl 1 &, <&>, ??, &~
type ALens s t a b = LensLike (Pretext (->) a b) s t a b
type ALens' s a = ALens s s a a
type AnIndexedLens i s t a b = Optical (Indexed i) (->) (Pretext (Indexed i) a b) s t a b
type AnIndexedLens' i s a = AnIndexedLens i s s a a
lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
lens sa sbt afb s = sbt s <$> afb (sa s)
{-# INLINE lens #-}
iplens :: (s -> a) -> (s -> b -> t) -> IndexPreservingLens s t a b
iplens sa sbt pafb = cotabulate $ \ws -> sbt (extract ws) <$> corep pafb (sa <$> ws)
{-# INLINE iplens #-}
ilens :: (s -> (i, a)) -> (s -> b -> t) -> IndexedLens i s t a b
ilens sia sbt iafb s = sbt s <$> uncurry (indexed iafb) (sia s)
{-# INLINE ilens #-}
(&~) :: s -> State s a -> s
s &~ l = execState l s
{-# INLINE (&~) #-}
(%%~) :: Optical p q f s t a b -> p a (f b) -> q s (f t)
(%%~) = id
{-# INLINE (%%~) #-}
(%%=) :: MonadState s m => Over p ((,) r) s s a b -> p a (r, b) -> m r
#if MIN_VERSION_mtl(2,1,1)
l %%= f = State.state (l f)
#else
l %%= f = do
(r, s) <- State.gets (l f)
State.put s
return r
#endif
{-# INLINE (%%=) #-}
(&) :: a -> (a -> b) -> b
a & f = f a
{-# INLINE (&) #-}
(<&>) :: Functor f => f a -> (a -> b) -> f b
as <&> f = f <$> as
{-# INLINE (<&>) #-}
(??) :: Functor f => f (a -> b) -> a -> f b
fab ?? a = fmap ($ a) fab
{-# INLINE (??) #-}
inside :: Corepresentable p => ALens s t a b -> Lens (p e s) (p e t) (p e a) (p e b)
inside l f es = o <$> f i where
i = cotabulate $ \ e -> ipos $ l sell (corep es e)
o ea = cotabulate $ \ e -> ipeek (corep ea e) $ l sell (corep es e)
{-# INLINE inside #-}
choosing :: Functor f
=> LensLike f s t a b
-> LensLike f s' t' a b
-> LensLike f (Either s s') (Either t t') a b
choosing l _ f (Left a) = Left <$> l f a
choosing _ r f (Right a') = Right <$> r f a'
{-# INLINE choosing #-}
chosen :: IndexPreservingLens (Either a a) (Either b b) a b
chosen pafb = cotabulate $ \weaa -> corep (either id id `lmap` pafb) weaa <&> \b -> case extract weaa of
Left _ -> Left b
Right _ -> Right b
{-# INLINE chosen #-}
alongside :: LensLike (AlongsideLeft f b') s t a b
-> LensLike (AlongsideRight f t) s' t' a' b'
-> LensLike f (s, s') (t, t') (a, a') (b, b')
alongside l1 l2 f (a1, a2)
= getAlongsideRight $ l2 ?? a2 $ \b2 -> AlongsideRight
$ getAlongsideLeft $ l1 ?? a1 $ \b1 -> AlongsideLeft
$ f (b1,b2)
{-# INLINE alongside #-}
locus :: IndexedComonadStore p => Lens (p a c s) (p b c s) a b
locus f w = (`iseek` w) <$> f (ipos w)
{-# INLINE locus #-}
cloneLens :: ALens s t a b -> Lens s t a b
cloneLens l afb s = runPretext (l sell s) afb
{-# INLINE cloneLens #-}
cloneIndexPreservingLens :: ALens s t a b -> IndexPreservingLens s t a b
cloneIndexPreservingLens l pafb = cotabulate $ \ws -> runPretext (l sell (extract ws)) $ \a -> corep pafb (a <$ ws)
{-# INLINE cloneIndexPreservingLens #-}
cloneIndexedLens :: AnIndexedLens i s t a b -> IndexedLens i s t a b
cloneIndexedLens l f s = runPretext (l sell s) (Indexed (indexed f))
{-# INLINE cloneIndexedLens #-}
(<%~) :: Profunctor p => Optical p q ((,) b) s t a b -> p a b -> q s (b, t)
l <%~ f = l $ rmap (\t -> (t, t)) f
{-# INLINE (<%~) #-}
(<+~) :: Num a => Optical (->) q ((,)a) s t a a -> a -> q s (a, t)
l <+~ a = l <%~ (+ a)
{-# INLINE (<+~) #-}
(<-~) :: Num a => Optical (->) q ((,)a) s t a a -> a -> q s (a, t)
l <-~ a = l <%~ subtract a
{-# INLINE (<-~) #-}
(<*~) :: Num a => Optical (->) q ((,)a) s t a a -> a -> q s (a, t)
l <*~ a = l <%~ (* a)
{-# INLINE (<*~) #-}
(<//~) :: Fractional a => Optical (->) q ((,)a) s t a a -> a -> q s (a, t)
l <//~ a = l <%~ (/ a)
{-# INLINE (<//~) #-}
(<^~) :: (Num a, Integral e) => Optical (->) q ((,)a) s t a a -> e -> q s (a, t)
l <^~ e = l <%~ (^ e)
{-# INLINE (<^~) #-}
(<^^~) :: (Fractional a, Integral e) => Optical (->) q ((,)a) s t a a -> e -> q s (a, t)
l <^^~ e = l <%~ (^^ e)
{-# INLINE (<^^~) #-}
(<**~) :: Floating a => Optical (->) q ((,)a) s t a a -> a -> q s (a, t)
l <**~ a = l <%~ (** a)
{-# INLINE (<**~) #-}
(<||~) :: Optical (->) q ((,)Bool) s t Bool Bool -> Bool -> q s (Bool, t)
l <||~ b = l <%~ (|| b)
{-# INLINE (<||~) #-}
(<&&~) :: Optical (->) q ((,)Bool) s t Bool Bool -> Bool -> q s (Bool, t)
l <&&~ b = l <%~ (&& b)
{-# INLINE (<&&~) #-}
(<<%~) :: Strong p => Optical p q ((,)a) s t a b -> p a b -> q s (a, t)
(<<%~) l = l . lmap (\a -> (a, a)) . second'
{-# INLINE (<<%~) #-}
(<<.~) :: Optical (->) q ((,)a) s t a b -> b -> q s (a, t)
l <<.~ b = l $ \a -> (a, b)
{-# INLINE (<<.~) #-}
(<<+~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
l <<+~ b = l $ \a -> (a, a + b)
{-# INLINE (<<+~) #-}
(<<-~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
l <<-~ b = l $ \a -> (a, a - b)
{-# INLINE (<<-~) #-}
(<<*~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
l <<*~ b = l $ \a -> (a, a * b)
{-# INLINE (<<*~) #-}
(<<//~) :: Fractional a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
l <<//~ b = l $ \a -> (a, a / b)
{-# INLINE (<<//~) #-}
(<<^~) :: (Num a, Integral e) => Optical' (->) q ((,) a) s a -> e -> q s (a, s)
l <<^~ e = l $ \a -> (a, a ^ e)
{-# INLINE (<<^~) #-}
(<<^^~) :: (Fractional a, Integral e) => Optical' (->) q ((,) a) s a -> e -> q s (a, s)
l <<^^~ e = l $ \a -> (a, a ^^ e)
{-# INLINE (<<^^~) #-}
(<<**~) :: Floating a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
l <<**~ e = l $ \a -> (a, a ** e)
{-# INLINE (<<**~) #-}
(<<||~) :: Optical' (->) q ((,) Bool) s Bool -> Bool -> q s (Bool, s)
l <<||~ b = l $ \a -> (a, b || a)
{-# INLINE (<<||~) #-}
(<<&&~) :: Optical' (->) q ((,) Bool) s Bool -> Bool -> q s (Bool, s)
l <<&&~ b = l $ \a -> (a, b && a)
{-# INLINE (<<&&~) #-}
(<<<>~) :: Monoid r => Optical' (->) q ((,) r) s r -> r -> q s (r, s)
l <<<>~ b = l $ \a -> (a, a `mappend` b)
{-# INLINE (<<<>~) #-}
(<%=) :: (Profunctor p, MonadState s m) => Over p ((,)b) s s a b -> p a b -> m b
l <%= f = l %%= rmap (\b -> (b, b)) f
{-# INLINE (<%=) #-}
(<+=) :: (MonadState s m, Num a) => LensLike' ((,)a) s a -> a -> m a
l <+= a = l <%= (+ a)
{-# INLINE (<+=) #-}
(<-=) :: (MonadState s m, Num a) => LensLike' ((,)a) s a -> a -> m a
l <-= a = l <%= subtract a
{-# INLINE (<-=) #-}
(<*=) :: (MonadState s m, Num a) => LensLike' ((,)a) s a -> a -> m a
l <*= a = l <%= (* a)
{-# INLINE (<*=) #-}
(<//=) :: (MonadState s m, Fractional a) => LensLike' ((,)a) s a -> a -> m a
l <//= a = l <%= (/ a)
{-# INLINE (<//=) #-}
(<^=) :: (MonadState s m, Num a, Integral e) => LensLike' ((,)a) s a -> e -> m a
l <^= e = l <%= (^ e)
{-# INLINE (<^=) #-}
(<^^=) :: (MonadState s m, Fractional a, Integral e) => LensLike' ((,)a) s a -> e -> m a
l <^^= e = l <%= (^^ e)
{-# INLINE (<^^=) #-}
(<**=) :: (MonadState s m, Floating a) => LensLike' ((,)a) s a -> a -> m a
l <**= a = l <%= (** a)
{-# INLINE (<**=) #-}
(<||=) :: MonadState s m => LensLike' ((,)Bool) s Bool -> Bool -> m Bool
l <||= b = l <%= (|| b)
{-# INLINE (<||=) #-}
(<&&=) :: MonadState s m => LensLike' ((,)Bool) s Bool -> Bool -> m Bool
l <&&= b = l <%= (&& b)
{-# INLINE (<&&=) #-}
(<<%=) :: (Strong p, MonadState s m) => Over p ((,)a) s s a b -> p a b -> m a
l <<%= f = l %%= lmap (\a -> (a,a)) (second' f)
{-# INLINE (<<%=) #-}
(<<.=) :: MonadState s m => LensLike ((,)a) s s a b -> b -> m a
l <<.= b = l %%= \a -> (a,b)
{-# INLINE (<<.=) #-}
(<<+=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
l <<+= n = l %%= \a -> (a, a + n)
{-# INLINE (<<+=) #-}
(<<-=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
l <<-= n = l %%= \a -> (a, a - n)
{-# INLINE (<<-=) #-}
(<<*=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
l <<*= n = l %%= \a -> (a, a * n)
{-# INLINE (<<*=) #-}
(<<//=) :: (MonadState s m, Fractional a) => LensLike' ((,) a) s a -> a -> m a
l <<//= n = l %%= \a -> (a, a / n)
{-# INLINE (<<//=) #-}
(<<^=) :: (MonadState s m, Num a, Integral e) => LensLike' ((,) a) s a -> e -> m a
l <<^= n = l %%= \a -> (a, a ^ n)
{-# INLINE (<<^=) #-}
(<<^^=) :: (MonadState s m, Fractional a, Integral e) => LensLike' ((,) a) s a -> e -> m a
l <<^^= n = l %%= \a -> (a, a ^^ n)
{-# INLINE (<<^^=) #-}
(<<**=) :: (MonadState s m, Floating a) => LensLike' ((,) a) s a -> a -> m a
l <<**= n = l %%= \a -> (a, a ** n)
{-# INLINE (<<**=) #-}
(<<||=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool
l <<||= b = l %%= \a -> (a, a || b)
{-# INLINE (<<||=) #-}
(<<&&=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool
l <<&&= b = l %%= \a -> (a, a && b)
{-# INLINE (<<&&=) #-}
(<<<>=) :: (MonadState s m, Monoid r) => LensLike' ((,) r) s r -> r -> m r
l <<<>= b = l %%= \a -> (a, a `mappend` b)
{-# INLINE (<<<>=) #-}
(<<~) :: MonadState s m => ALens s s a b -> m b -> m b
l <<~ mb = do
b <- mb
modify $ \s -> ipeek b (l sell s)
return b
{-# INLINE (<<~) #-}
(<<>~) :: Monoid m => Optical (->) q ((,)m) s t m m -> m -> q s (m, t)
l <<>~ m = l <%~ (`mappend` m)
{-# INLINE (<<>~) #-}
(<<>=) :: (MonadState s m, Monoid r) => LensLike' ((,)r) s r -> r -> m r
l <<>= r = l <%= (`mappend` r)
{-# INLINE (<<>=) #-}
overA :: Arrow ar => LensLike (Context a b) s t a b -> ar a b -> ar s t
overA l p = arr (\s -> let (Context f a) = l sell s in (f, a))
>>> second p
>>> arr (uncurry id)
(<%@~) :: Optical (Indexed i) q ((,) b) s t a b -> (i -> a -> b) -> q s (b, t)
l <%@~ f = l (Indexed $ \i a -> let b = f i a in (b, b))
{-# INLINE (<%@~) #-}
(<<%@~) :: Optical (Indexed i) q ((,) a) s t a b -> (i -> a -> b) -> q s (a, t)
l <<%@~ f = l $ Indexed $ \i a -> second' (f i) (a,a)
{-# INLINE (<<%@~) #-}
(%%@~) :: IndexedLensLike i f s t a b -> (i -> a -> f b) -> s -> f t
(%%@~) l = l .# Indexed
{-# INLINE (%%@~) #-}
(%%@=) :: MonadState s m => IndexedLensLike i ((,) r) s s a b -> (i -> a -> (r, b)) -> m r
#if MIN_VERSION_mtl(2,1,0)
l %%@= f = State.state (l %%@~ f)
#else
l %%@= f = do
(r, s) <- State.gets (l %%@~ f)
State.put s
return r
#endif
{-# INLINE (%%@=) #-}
(<%@=) :: MonadState s m => IndexedLensLike i ((,) b) s s a b -> (i -> a -> b) -> m b
l <%@= f = l %%@= \ i a -> let b = f i a in (b, b)
{-# INLINE (<%@=) #-}
(<<%@=) :: MonadState s m => IndexedLensLike i ((,) a) s s a b -> (i -> a -> b) -> m a
#if MIN_VERSION_mtl(2,1,0)
l <<%@= f = State.state (l (Indexed $ \ i a -> (a, f i a)))
#else
l <<%@= f = do
(r, s) <- State.gets (l (Indexed $ \ i a -> (a, f i a)))
State.put s
return r
#endif
{-# INLINE (<<%@=) #-}
(^#) :: s -> ALens s t a b -> a
s ^# l = ipos (l sell s)
{-# INLINE (^#) #-}
storing :: ALens s t a b -> b -> s -> t
storing l b s = ipeek b (l sell s)
{-# INLINE storing #-}
( #~ ) :: ALens s t a b -> b -> s -> t
( #~ ) l b s = ipeek b (l sell s)
{-# INLINE ( #~ ) #-}
( #%~ ) :: ALens s t a b -> (a -> b) -> s -> t
( #%~ ) l f s = ipeeks f (l sell s)
{-# INLINE ( #%~ ) #-}
( #%%~ ) :: Functor f => ALens s t a b -> (a -> f b) -> s -> f t
( #%%~ ) l f s = runPretext (l sell s) f
{-# INLINE ( #%%~ ) #-}
( #= ) :: MonadState s m => ALens s s a b -> b -> m ()
l #= f = modify (l #~ f)
{-# INLINE ( #= ) #-}
( #%= ) :: MonadState s m => ALens s s a b -> (a -> b) -> m ()
l #%= f = modify (l #%~ f)
{-# INLINE ( #%= ) #-}
(<#%~) :: ALens s t a b -> (a -> b) -> s -> (b, t)
l <#%~ f = \s -> runPretext (l sell s) $ \a -> let b = f a in (b, b)
{-# INLINE (<#%~) #-}
(<#%=) :: MonadState s m => ALens s s a b -> (a -> b) -> m b
l <#%= f = l #%%= \a -> let b = f a in (b, b)
{-# INLINE (<#%=) #-}
( #%%= ) :: MonadState s m => ALens s s a b -> (a -> (r, b)) -> m r
#if MIN_VERSION_mtl(2,1,1)
l #%%= f = State.state $ \s -> runPretext (l sell s) f
#else
l #%%= f = do
p <- State.gets (l sell)
let (r, t) = runPretext p f
State.put t
return r
#endif
{-# INLINE ( #%%= ) #-}
(<#~) :: ALens s t a b -> b -> s -> (b, t)
l <#~ b = \s -> (b, storing l b s)
{-# INLINE (<#~) #-}
(<#=) :: MonadState s m => ALens s s a b -> b -> m b
l <#= b = do
l #= b
return b
{-# INLINE (<#=) #-}
devoid :: Over p f Void Void a b
devoid _ = absurd
{-# INLINE devoid #-}
united :: Lens' a ()
united f v = f () <&> \ () -> v
{-# INLINE united #-}