module Data.Lens.Partial.Common where
import Prelude hiding ((.), id, null)
import Control.Applicative
import Control.Category
import Data.Lens.Common (Lens(..))
import Control.Comonad.Trans.Store
import Data.Functor.Identity
import Data.Functor.Coproduct
newtype PartialLens a b = PLens (a -> Maybe (Store b a))
runPLens :: PartialLens a b -> a -> (Coproduct Identity (Store b)) a
runPLens (PLens f) a = maybe (left (Identity a)) right (f a)
instance Category PartialLens where
id = totalLens id
PLens f . PLens g = PLens $ \a -> do
(StoreT wba b) <- g a
(StoreT wcb c) <- f b
return (StoreT ((.) <$> wba <*> wcb) c)
null :: PartialLens a b
null = PLens (const Nothing)
totalLens :: Lens a b -> PartialLens a b
totalLens (Lens f) = PLens (Just . f)
getPL :: PartialLens a b -> a -> Maybe b
getPL (PLens f) a = pos <$> f a
trySetPL :: PartialLens a b -> a -> Maybe (b -> a)
trySetPL (PLens f) a = flip peek <$> f a
setPL :: PartialLens a b -> b -> a -> a
setPL (PLens f) b a = maybe a (peek b) (f a)
modPL :: PartialLens a b -> (b -> b) -> a -> a
modPL (PLens f) g a = maybe a (peeks g) (f a)
infixr 0 ^$
(^$) = getPL
infixr 9 ^.
(^.) = flip getPL
infixr 4 ^=
(^=) :: PartialLens a b -> b -> a -> a
(^=) = setPL
infixr 4 ^%=
(^%=) :: PartialLens a b -> (b -> b) -> a -> a
(^%=) = modPL
infixr 4 ^+=, ^-=, ^*=
(^+=), (^-=), (^*=) :: Num b => PartialLens a b -> b -> a -> a
l ^+= n = l ^%= (+ n)
l ^-= n = l ^%= subtract n
l ^*= n = l ^%= (* n)
infixr 4 ^/=
(^/=) :: Fractional b => PartialLens a b -> b -> a -> a
l ^/= r = l ^%= (/ r)
maybeLens :: PartialLens (Maybe a) a
maybeLens = PLens $ \ma -> do
a <- ma
return (StoreT (pure Just) a)
leftLens :: PartialLens (Either a b) a
leftLens = PLens $ either (Just . StoreT (pure Left)) (const Nothing)
rightLens :: PartialLens (Either a b) b
rightLens = PLens $ either (const Nothing) (Just . StoreT (pure Right))
headLens :: PartialLens [a] a
headLens = PLens f
where
f [] = Nothing
f (h:t) = Just (StoreT (pure (:t)) h)
tailLens :: PartialLens [a] [a]
tailLens = PLens f
where
f [] = Nothing
f (h:t) = Just (StoreT (pure (h:)) t)