module Control.Imperative.Operators
(
liftOp
, liftOp2
, (~$), (~*)
, (/.), (%.), (^.), (&&.), (||.)
, (==.), (/=.), (>=.), (<=.), (>.), (<.), notR, (&.), (|.), xorR, complR, (<<.), (>>.)
, assignModify
, (=:), (+=:), (-=:), (*=:), (/=:), (%=:), (^=:), (//=:), (**=:), (<>=:)
, (&&=:), (||=:), (&=:), (|=:), (<<=:), (>>=:)
, (<~), (<&~)
) where
import Control.Imperative.Internal
import Control.Monad.Base
import Data.Bits
import Data.Monoid
(~$) :: Monad m => (a -> b) -> Ref m a -> Ref m b
(~$) = liftOp
(~*) :: Monad m => Ref m (a -> b) -> Ref m a -> Ref m b
(~*) = liftOp2 ($)
infixl 4 ~$, ~*
(/.), (%.) :: Monad m => Integral a => Ref m a -> Ref m a -> Ref m a
(/.) = liftOp2 div
(%.) = liftOp2 mod
infixl 7 /., %.
(^.) :: (Num a, Integral b, Monad m) => Ref m a -> Ref m b -> Ref m a
(^.) = liftOp2 (^)
infixr 8 ^.
(&&.), (||.) :: Monad m => Ref m Bool -> Ref m Bool -> Ref m Bool
(&&.) = liftOp2 (&&)
(||.) = liftOp2 (||)
infixr 3 &&.
infixr 2 ||.
(==.), (/=.), (>=.), (<=.), (<.), (>.) :: (Ord a, Monad m) => Ref m a -> Ref m a -> Ref m Bool
(==.) = liftOp2 (==)
(/=.) = liftOp2 (/=)
(>=.) = liftOp2 (>=)
(<=.) = liftOp2 (<=)
(>.) = liftOp2 (>)
(<.) = liftOp2 (<)
infixl 4 ==., /=., >=., <=., <., >.
notR :: Monad m => Ref m Bool -> Ref m Bool
notR = liftOp not
(&.), (|.), xorR :: (Bits a, Monad m) => Ref m a -> Ref m a -> Ref m a
(&.) = liftOp2 (.&.)
(|.) = liftOp2 (.|.)
xorR = liftOp2 xor
infixl 7 &.
infixl 5 |.
(<<.), (>>.) :: (Bits a, Monad m) => Ref m a -> Ref m Int -> Ref m a
(<<.) = liftOp2 shiftL
(>>.) = liftOp2 shiftR
infixl 5 <<., >>.
complR :: (Bits a, Monad m) => Ref m a -> Ref m a
complR = liftOp complement
assignModify :: MonadBase (BaseEff m) m => (a -> b -> a) -> Ref (BaseEff m) a -> Ref (BaseEff m) b -> m ()
assignModify f v w = ref (liftOp2 f v w) >>= assign v
(=:) :: MonadBase (BaseEff m) m => Ref (BaseEff m) a -> Ref (BaseEff m) a -> m ()
(=:) v w = ref w >>= assign v
(+=:), (-=:), (*=:) :: (Num a, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) a -> m ()
(+=:) = assignModify (+)
(-=:) = assignModify ()
(*=:) = assignModify (*)
(/=:), (%=:) :: (Integral a, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) a -> m ()
(/=:) = assignModify div
(%=:) = assignModify mod
(^=:) :: (Num a, Integral b, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) b -> m ()
(^=:) = assignModify (^)
(//=:) :: (Fractional a, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) a -> m ()
(//=:) = assignModify (/)
(**=:) :: (Floating a, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) a -> m ()
(**=:) = assignModify (**)
(&=:), (|=:) :: (Bits a, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) a -> m ()
(&=:) = assignModify (.&.)
(|=:) = assignModify (.|.)
(<<=:), (>>=:) :: (Bits a, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) Int -> m ()
(<<=:) = assignModify shiftL
(>>=:) = assignModify shiftR
(<>=:) :: (Monoid a, MonadBase (BaseEff m) m) => Ref (BaseEff m) a -> Ref (BaseEff m) a -> m ()
(<>=:) = assignModify (<>)
(&&=:), (||=:) :: MonadBase (BaseEff m) m => Ref (BaseEff m) Bool -> Ref (BaseEff m) Bool -> m ()
(&&=:) = assignModify (&&)
(||=:) = assignModify (||)
(<~) :: MonadBase (BaseEff m) m => Ref (BaseEff m) a -> m a -> m ()
v <~ m = m >>= assign v
(<&~) :: MonadBase (BaseEff m) m => Ref (BaseEff m) a -> (a -> a) -> m ()
v <&~ f = ref v >>= assign v . f
infix 2 =:, +=:, -=:, *=:, %=:, /=:, ^=:, //=:, **=:
infix 2 &&=:, ||=:, &=:, |=:, <<=:, >>=:, <>=:
infixr 2 <~
infix 2 <&~