{-# LANGUAGE RankNTypes #-}
-- | This module implements a minimal lens type.
module Language.Thrift.Internal.Lens
    ( Lens
    , lens
    , set
    , view
    ) where

import Data.Functor.Identity (Identity (..))

import qualified Control.Applicative as A

type Lens s a = forall f. Functor f => (a -> f a) -> s -> f s

lens :: (s -> a) -> (s -> a -> s) -> Lens s a
lens :: forall s a. (s -> a) -> (s -> a -> s) -> Lens s a
lens s -> a
getter s -> a -> s
setter a -> f a
f s
s = s -> a -> s
setter s
s (a -> s) -> f a -> f s
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` a -> f a
f (s -> a
getter s
s)

set :: Lens s a -> a -> s -> s
set :: forall s a. Lens s a -> a -> s -> s
set Lens s a
l a
a = Identity s -> s
forall a. Identity a -> a
runIdentity (Identity s -> s) -> (s -> Identity s) -> s -> s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Identity a) -> s -> Identity s
Lens s a
l (\a
_ -> a -> Identity a
forall a. a -> Identity a
Identity a
a)

view :: Lens s a -> s -> a
view :: forall s a. Lens s a -> s -> a
view Lens s a
l = Const a s -> a
forall {k} a (b :: k). Const a b -> a
A.getConst (Const a s -> a) -> (s -> Const a s) -> s -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Const a a) -> s -> Const a s
Lens s a
l a -> Const a a
forall {k} a (b :: k). a -> Const a b
A.Const