module Data.Lens.Common
( Lens
, Lens'
, lens
, getL
, setL
, modL
, fstLens
, sndLens
, showLens
, listLens
, maybeLens
) where
import Data.Maybe
import Control.Applicative
import Control.Monad.Identity
type Lens s t a b = Functor f => (a -> f b) -> s -> f t
type Lens' s a = Lens s s a a
lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
lens sa sbt afb s = sbt s <$> afb (sa s)
iso :: (s -> a) -> (b -> t) -> Lens s t a b
iso f g = lens f $ flip $ const . g
getL :: Lens' a b -> a -> b
getL l = getConst . l Const
setL :: Lens s t a b -> b -> s -> t
setL l s = runIdentity . l (const $ Identity s)
modL :: Lens s t a b -> (a -> b) -> s -> t
modL l f = runIdentity . l (Identity . f)
fstLens :: Lens (x,b) (y,b) x y
fstLens = lens fst $ \(a,b) x -> (x,b)
sndLens :: Lens (a,x) (a,y) x y
sndLens = lens snd $ \(a,b) x -> (a,x)
showLens :: (Show a, Read a) => Lens' a String
showLens = lens show $ \def s -> maybe def fst $ listToMaybe $ reads s
listLens :: Lens' (Bool, (a, [a])) [a]
listLens = lens get set where
get (False, _) = []
get (True, (l, r)) = l: r
set (_, x) [] = (False, x)
set _ (l: r) = (True, (l, r))
maybeLens :: Lens' (Bool, a) (Maybe a)
maybeLens = lens (\(b,a) -> if b then Just a else Nothing)
(\(_,a) x -> maybe (False, a) (\a' -> (True, a')) x)