module Control.Reference.Operators where
import Control.Reference.Representation
import Control.Monad.Identity
infixl 4 .~
infixl 4 .=
infixl 4 %~
infixl 4 %~=
infixl 4 %=
infixl 4 ^.
infixl 4 ^?
(^.) :: s -> Reference wm Identity s t a b -> a
a ^. l = runIdentity (a ^? l)
(^?) :: s -> Reference wm rm s t a b -> rm a
a ^? l = lensGet l a
(.~) :: Reference Identity rm s t a b -> b -> (s -> t)
l .~ v = runIdentity . (l .= v)
(.=) :: Monad rw => Reference rw rm s t a b -> b -> (s -> rw t)
l .= v = lensSet l v
(%~) :: Reference Identity rm s t a b -> (a -> b) -> (s -> t)
l %~ trf = runIdentity . lensUpdate l (return . trf)
(%~=) :: Monad rw => Reference rw rm s t a b -> (a -> b) -> (s -> rw t)
l %~= trf = lensUpdate l (return . trf)
(%=) :: Reference rw rm s t a b -> (a -> rw b) -> (s -> rw t)
l %= trf = lensUpdate l trf
(%!) :: Monad rw => Reference rw rm s s a a -> (a -> rw c) -> (s -> rw s)
l %! act = lensUpdate l (\v -> act v >> return v)
(&) :: forall w r1 r2 s t c d a b . ( MonadCompose r1 r2 )
=> Reference w r1 s t c d -> Reference w r2 c d a b
-> Reference w (ResultMonad r1 r2) s t a b
(&) l1 l2 = Reference (\s -> (liftMC1 phr (lensGet l1 s)) >>= (liftMC2 phr . lensGet l2))
(lensUpdate l1 . lensSet l2)
(lensUpdate l1 . lensUpdate l2)
where phr = newComposePhantom
infixl 6 &
(&+&) :: forall w r1 r2 r12 r3 a s
. (Monad w, MonadPlus r3, MonadCompose r1 r2, r12 ~ ResultMonad r1 r2
, MonadCompose r12 [], r3 ~ (ResultMonad r12 []))
=> Reference w r1 s s a a -> Reference w r2 s s a a
-> Reference w r3 s s a a
l1 &+& l2 = Reference (\a -> liftMC1 cf2 (liftMC1 cf1 (a ^? l1))
`mplus` liftMC1 cf2 (liftMC2 cf1 (a ^? l2)))
(\v a -> (l1 .= v) a >>= l2 .= v )
(\trf a -> (l1 %= trf) a >>= (l2 %= trf) )
where cf1 = newComposePhantom
cf2 = newComposePhantom :: ComposePhantom r12 []
infixl 5 &+&