module Control.Monad.Trans.Order.Representation (
OrderTRep (OrderTRep),
performT,
getOrderToken,
newMinimum,
newMaximum,
newAfter,
newBefore,
state,
StateMonadTrans (..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
import Control.Monad.Trans.Class
import Control.Monad.IO.Class
import Data.Order.Pair.Type
import Data.Order.Element.Type
import Data.Order.Representation
import Data.Order.Element.Representation (ElementRep)
import qualified Data.Order.Element.Representation as ElementRep
import System.IO.Unsafe
import Unsafe.Coerce
infixl 4 <$!
infixl 4 <*>!
infixl 4 *>!
infixl 4 <*!
infixl 3 <|>!
infixl 1 >>=!
infixl 1 >>!
newtype OrderTRep t o (m :: * -> *) a = OrderTRep {
runOrderTRep :: forall o' e' . t (OrderRep o' e') m a
}
instance (StateMonadTrans t, Functor f) => Functor (OrderTRep t o f) where
fmap fun (OrderTRep comp) = OrderTRep $ fmap' fun comp
val <$ OrderTRep comp = OrderTRep $ val <$! comp
instance (StateMonadTrans t, Monad f) => Applicative (OrderTRep t o f) where
pure val = OrderTRep $ pure' val
OrderTRep funComp <*> OrderTRep valComp = OrderTRep $ funComp <*>! valComp
OrderTRep comp1 *> OrderTRep comp2 = OrderTRep $ comp1 *>! comp2
OrderTRep comp1 <* OrderTRep comp2 = OrderTRep $ comp1 <*! comp2
instance (StateMonadTrans t, MonadPlus m) => Alternative (OrderTRep t o m) where
empty = OrderTRep $ empty'
OrderTRep comp1 <|> OrderTRep comp2 = OrderTRep $ comp1 <|>! comp2
some (OrderTRep comp) = OrderTRep $ some' comp
many (OrderTRep comp) = OrderTRep $ many' comp
instance (StateMonadTrans t, Monad m) => Monad (OrderTRep t o m) where
OrderTRep comp >>= fun = OrderTRep $ comp >>=! runOrderTRep . fun
OrderTRep comp1 >> OrderTRep comp2 = OrderTRep $ comp1 >>! comp2
return val = OrderTRep $ return' val
fail msg = OrderTRep $ fail' msg
instance (StateMonadTrans t, MonadPlus m) => MonadPlus (OrderTRep t o m) where
mzero = OrderTRep $ mzero'
mplus (OrderTRep comp1) (OrderTRep comp2) = OrderTRep $ mplus' comp1 comp2
instance (StateMonadTrans t, MonadFix m) => MonadFix (OrderTRep t o m) where
mfix fun = OrderTRep $ mfix' (runOrderTRep . fun)
instance StateMonadTrans t => MonadTrans (OrderTRep t o) where
lift struct = OrderTRep $ lift' struct
instance (StateMonadTrans t, MonadIO m) => MonadIO (OrderTRep t o m) where
liftIO io = OrderTRep $ liftIO' io
performT :: (StateMonadTrans t, Functor f)
=> (a -> OrderTRep t o f b)
-> a
-> OrderRep o' e'
-> f (OrderPair o b)
performT fun val orderRep = OrderPair <$> struct where
struct = (runStateT $ runOrderTRep $ fun val) orderRep
getOrderToken :: (StateMonadTrans t, Applicative f) => OrderTRep t o f ()
getOrderToken = OrderTRep $ state $ \ orderRep -> (orderRep `seq` (), orderRep)
newMinimum :: (StateMonadTrans t, Applicative f)
=> OrderTRep t o f (Element o)
newMinimum = fromRepNew ElementRep.newMinimum
newMaximum :: (StateMonadTrans t, Applicative f)
=> OrderTRep t o f (Element o)
newMaximum = fromRepNew ElementRep.newMaximum
newAfter :: (StateMonadTrans t, Applicative f)
=> Element o
-> OrderTRep t o f (Element o)
newAfter (Element elemRep) = fromRepNewNeighbor ElementRep.newAfter elemRep
newBefore :: (StateMonadTrans t, Applicative f)
=> Element o
-> OrderTRep t o f (Element o)
newBefore (Element elemRep) = fromRepNewNeighbor ElementRep.newBefore elemRep
fromRepNewNeighbor :: (StateMonadTrans t, Applicative f)
=> (forall o' e' . ElementRep o' e' ->
OrderRep o' e' ->
IO (ElementRep o' e'))
-> ElementRep o'' e''
-> OrderTRep t o f (Element o)
fromRepNewNeighbor repNewNeighbor elemRep = orderTRep where
orderTRep = fromRepNew (repNewNeighbor (unsafeCoerce elemRep))
fromRepNew :: (StateMonadTrans t, Applicative f)
=> (forall o' e' . OrderRep o' e' -> IO (ElementRep o' e'))
-> OrderTRep t o f (Element o)
fromRepNew repNew = OrderTRep $ state fun where
fun orderRep = (elem, elem `seq` orderRep) where
elem = unsafePerformIO $ Element <$> repNew orderRep
state :: (StateMonadTrans t, Applicative f) => (s -> (a, s)) -> t s f a
state fun = stateT $ pure . fun
class StateMonadTrans t where
stateT :: (s -> f (a, s)) -> t s f a
runStateT :: t s f a -> s -> f (a, s)
fmap' :: Functor f => (a -> b) -> t s f a -> t s f b
(<$!) :: Functor f => b -> t s f a -> t s f b
pure' :: Monad m => a -> t s m a
(<*>!) :: Monad m => t s m (a -> b) -> t s m a -> t s m b
(*>!) :: Monad m => t s m a -> t s m b -> t s m b
(<*!) :: Monad m => t s m a -> t s m b -> t s m a
empty' :: MonadPlus m => t s m a
(<|>!) :: MonadPlus m => t s m a -> t s m a -> t s m a
some' :: MonadPlus m => t s m a -> t s m [a]
many' :: MonadPlus m => t s m a -> t s m [a]
(>>=!) :: Monad m => t s m a -> (a -> t s m b) -> t s m b
(>>!) :: Monad m => t s m a -> t s m b -> t s m b
return' :: Monad m => a -> t s m a
fail' :: Monad m => String -> t s m a
mzero' :: MonadPlus m => t s m a
mplus' :: MonadPlus m => t s m a -> t s m a -> t s m a
mfix' :: MonadFix m => (a -> t s m a) -> t s m a
lift' :: Monad m => m a -> t s m a
liftIO' :: MonadIO m => IO a -> t s m a