module Control.Monad.Trans.Order.Strict (
Order,
perform,
OrderT,
performT,
getOrderToken,
newMinimum,
newMaximum,
newAfter,
newBefore,
lazyToStrictOrderT,
strictToLazyOrderT
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
import Control.Monad.Trans.Class (MonadTrans)
import qualified Control.Monad.Trans.Class as Trans (lift)
import Control.Monad.IO.Class
import qualified Control.Monad.Trans.State.Strict as Strict
import Control.Monad.Trans.Order.Representation
(OrderTRep (OrderTRep), StateMonadTrans (..))
import qualified Control.Monad.Trans.Order.Representation as OrderTRep
import qualified Control.Monad.Trans.Order.Lazy.Type as Lazy (OrderT (OrderT))
import Data.Functor.Identity
import Data.Order.Pair.Type
import Data.Order.Element
type Order o = OrderT o Identity
perform :: (a -> Order o b) -> OrderPair o a -> OrderPair o b
perform fun pair = runIdentity (performT fun pair)
newtype OrderT o m a = OrderT {
runOrderT :: OrderTRep Strict.StateT o m a
} deriving (
Functor,
Applicative,
Alternative,
Monad,
MonadPlus,
MonadFix,
MonadTrans,
MonadIO
)
instance StateMonadTrans Strict.StateT where
stateT = Strict.StateT
runStateT = Strict.runStateT
fmap' = fmap
(<$!) = (<$)
pure' = pure
(<*>!) = (<*>)
(*>!) = (*>)
(<*!) = (<*)
empty' = empty
(<|>!) = (<|>)
some' = some
many' = many
(>>=!) = (>>=)
(>>!) = (>>)
return' = return
fail' = fail
mzero' = mzero
mplus' = mplus
mfix' = mfix
lift' = Trans.lift
liftIO' = liftIO
performT :: Functor f
=> (a -> OrderT o f b)
-> OrderPair o a
-> f (OrderPair o b)
performT fun (OrderPair (val, orderRep)) = output where
output = OrderTRep.performT (runOrderT . fun) val orderRep
getOrderToken :: Applicative f => OrderT o f ()
getOrderToken = OrderT $ OrderTRep.getOrderToken
lift :: Functor f => f a -> OrderT o f a
lift struct = OrderT $ OrderTRep.lift struct
newMinimum :: Applicative f => OrderT o f (Element o)
newMinimum = OrderT $ OrderTRep.newMinimum
newMaximum :: Applicative f => OrderT o f (Element o)
newMaximum = OrderT $ OrderTRep.newMaximum
newAfter :: Applicative f => Element o -> OrderT o f (Element o)
newAfter elem = OrderT $ OrderTRep.newAfter elem
newBefore :: Applicative f => Element o -> OrderT o f (Element o)
newBefore elem = OrderT $ OrderTRep.newBefore elem
lazyToStrictOrderT :: Lazy.OrderT o m a -> OrderT o m a
lazyToStrictOrderT (Lazy.OrderT (OrderTRep comp)) = strictOrderT where
strictOrderT = OrderT $ OrderTRep $ stateT (runStateT comp)
strictToLazyOrderT :: OrderT o m a -> Lazy.OrderT o m a
strictToLazyOrderT (OrderT (OrderTRep comp)) = lazyOrderT where
lazyOrderT = Lazy.OrderT $ OrderTRep $ stateT (runStateT comp)