{-# LANGUAGE CPP, TypeOperators #-}
module Data.Label.Total
( (:->)
, Total
, lens
, get
, modify
, set
, traverse
, lifted
)
where
#if MIN_VERSION_base(4,8,0)
import Prelude hiding (traverse)
#endif
import Control.Monad ((<=<), liftM)
import Data.Label.Poly (Lens)
import Data.Label.Point (Total)
import qualified Data.Label.Poly as Poly
{-# INLINE lens #-}
{-# INLINE get #-}
{-# INLINE modify #-}
{-# INLINE set #-}
type f :-> o = Lens Total f o
lens :: (f -> o)
-> ((o -> i) -> f -> g)
-> (f -> g) :-> (o -> i)
lens g s = Poly.lens g (uncurry s)
get :: ((f -> g) :-> (o -> i)) -> f -> o
get = Poly.get
modify :: (f -> g) :-> (o -> i) -> (o -> i) -> f -> g
modify = curry . Poly.modify
set :: ((f -> g) :-> (o -> i)) -> i -> f -> g
set = curry . Poly.set
traverse :: Functor m => (f -> g) :-> (o -> i) -> (o -> m i) -> f -> m g
traverse l m f = (\w -> set l w f) `fmap` m (get l f)
lifted
:: Monad m
=> (f -> g) :-> (m o -> m i)
-> (o -> i) :-> (m a -> m b)
-> (f -> g) :-> (m a -> m b)
lifted a b = lens (get b <=< get a) (modify a . liftM . modify b)