module Data.Label.Maybe
( (:~>)
, lens
, get
, set
, set'
, modify
, modify'
, embed
)
where
import Control.Arrow
import Control.Category
import Control.Monad.Identity
import Control.Monad.Trans.Maybe
import Data.Maybe
import Prelude hiding ((.), id)
import qualified Data.Label.Abstract as A
type MaybeLens f a = A.Lens (Kleisli (MaybeT Identity)) f a
type f :~> a = MaybeLens f a
run :: Kleisli (MaybeT Identity) f a -> f -> Maybe a
run l = runIdentity . runMaybeT . runKleisli l
lens :: (f -> Maybe a) -> (a -> f -> Maybe f) -> f :~> a
lens g s = A.lens (kl g) (kl (uncurry s))
where kl a = Kleisli (MaybeT . Identity . a)
get :: (f :~> a) -> f -> Maybe a
get l = run (A.get l)
set :: f :~> a -> a -> f -> Maybe f
set l v = run (A.set l . arr (v,))
set' :: (f :~> a) -> a -> f -> f
set' l v f = f `fromMaybe` set l v f
modify :: (f :~> a) -> (a -> a) -> f -> Maybe f
modify l m = run (A.modify l . arr (arr m,))
modify' :: (f :~> a) -> (a -> a) -> f -> f
modify' l m f = f `fromMaybe` modify l m f
embed :: A.Lens (->) f (Maybe a) -> f :~> a
embed l = lens (A.get l) (\a f -> Just (A.set l (Just a, f)))