mini-1.1.0.0: Mini/Optics/Lens.hs
{-# LANGUAGE RankNTypes #-}
-- | Compose polymorphic record updates with /van Laarhoven/ lenses
module Mini.Optics.Lens (
-- * Type
Lens,
-- * Construction
lens,
-- * Operations
view,
over,
set,
) where
import Control.Applicative (
Const (
Const,
getConst
),
)
import Data.Functor.Identity (
Identity (
Identity,
runIdentity
),
)
{-
- Type
-}
-- | A reference updating structures from /s/ to /t/ and fields from /a/ to /b/
type Lens s t a b = forall f. (Functor f) => (a -> f b) -> (s -> f t)
{-
- Construction
-}
-- | Make a lens from a getter and a setter
lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
lens sa sbt ab s = sbt s <$> ab (sa s)
{-
- Operations
-}
-- | Fetch the field referenced by a lens from a structure
view :: Lens s t a b -> s -> a
view o = getConst . o Const
-- | Update the field referenced by a lens with an operation on a structure
over :: Lens s t a b -> (a -> b) -> s -> t
over o ab = runIdentity . o (Identity . ab)
-- | Overwrite the field referenced by a lens with a value on a structure
set :: Lens s t a b -> b -> s -> t
set o b = runIdentity . o (const $ Identity b)