    {-# LANGUAGE TypeOperators #-}
    module Data.Label.Pure
    ( (:->)
    , lens
    , get
    , set
    , modify
    )
    where

    import qualified Data.Label.Abstract as A

    type PureLens f a = A.Lens (->) f a

    -- | Pure lens type specialized for pure accessor functions.

    type (f :-> a) = PureLens f a

    -- | Create a pure lens from a getter and a setter.
    --
    -- We expect the following law to hold:
    --
    -- > get l (set l a f) == a
    --
    -- Or, equivalently:
    --
    -- > set l (get l f) f == f

    lens :: (f -> a) -> (a -> f -> f) -> f :-> a
    lens g s = A.lens g (uncurry s)

    -- | Getter for a pure lens.

    get :: (f :-> a) -> f -> a
    get = A.get

    -- | Setter for a pure lens.

    set :: (f :-> a) -> a -> f -> f
    set = curry . A.set

    -- | Modifier for a pure lens.

    modify :: (f :-> a) -> (a -> a) -> f -> f
    modify = curry . A.modify