module Control.Monad.Trans.Order.Representation (
OrderTRep (OrderTRep),
performT,
getOrderToken,
lift,
newMinimum,
newMaximum,
newAfter,
newBefore,
state,
StateMonadTrans (..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
import Control.Monad.Trans.Class (MonadTrans)
import qualified Control.Monad.Trans.Class (lift)
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)
lift :: (StateMonadTrans t, Functor f) => f a -> OrderTRep t o f a
lift struct = OrderTRep $ stateT $ \ orderRep -> (, orderRep) <$> struct
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