fclabels-2.0.5.1: src/Data/Label/Mono.hs
{- | Lenses that only allow monomorphic updates. Monomorphic lenses are simply
polymorphic lenses with the input and output type variables constraint to the
same type. -}
{-# LANGUAGE
FlexibleInstances
, MultiParamTypeClasses
, TypeOperators
#-}
module Data.Label.Mono
( Lens
, lens
, get
, modify
, point
, set
, iso
-- * Specialized monomorphic lens operators.
, (:->)
, (:~>)
)
where
import Control.Category
import Control.Arrow
import Data.Label.Point (Point, Iso (..), Total, Partial)
import Prelude ()
import qualified Data.Label.Poly as Poly
{-# INLINE lens #-}
{-# INLINE get #-}
{-# INLINE modify #-}
{-# INLINE set #-}
{-# INLINE point #-}
{-# INLINE iso #-}
-------------------------------------------------------------------------------
-- | Abstract monomorphic lens datatype. The getter and setter functions work
-- in some category. Categories allow for effectful lenses, for example, lenses
-- that might fail or use state.
type Lens cat f o = Poly.Lens cat (f -> f) (o -> o)
-- | Create a lens out of a getter and setter.
lens :: cat f o -- ^ Getter.
-> (cat (cat o o, f) f) -- ^ Modifier.
-> Lens cat f o
lens = Poly.lens
-- | Get the getter arrow from a lens.
get :: Lens cat f o -> cat f o
get = Poly.get
-- | Get the modifier arrow from a lens.
modify :: Lens cat f o -> cat (cat o o, f) f
modify = Poly.modify
-- | Get the setter arrow from a lens.
set :: Arrow arr => Lens arr f o -> arr (o, f) f
set = Poly.set
-- | Create lens from a `Point`.
point :: Point cat f o f o -> Lens cat f o
point = Poly.point
-- | Lift an isomorphism into a `Lens`.
iso :: ArrowApply cat => Iso cat f o -> Lens cat f o
iso (Iso f b) = lens f (app . arr (\(m, v) -> (b . m . f, v)))
-------------------------------------------------------------------------------
-- | Total monomorphic lens.
type f :-> o = Lens Total f o
-- | Partial monomorphic lens.
type f :~> o = Lens Partial f o