order-maintenance-0.0.0.0: src/Control/Monad/Trans/Order/Strict.hs
module Control.Monad.Trans.Order.Strict (
-- * The Order monad
Order,
evalOrder,
evalOrderWith,
-- * The OrderT monad transformer
OrderT,
evalOrderT,
force,
-- * Elements
Element,
newMinimum,
newMaximum,
newAfter,
newBefore,
-- * Converting between lazy and strict OrderT
lazyToStrictOrderT,
strictToLazyOrderT
) where
-- Control
import Control.Monad
import Control.Applicative
import Control.Monad.Trans.Class
import Control.Monad.IO.Class
import qualified Control.Monad.Trans.State.Lazy
as Lazy
import Control.Monad.Trans.State.Strict
import Control.Monad.Trans.Order.Lazy
(Element)
import qualified Control.Monad.Trans.Order.Lazy
as Lazy
import Control.Monad.Trans.Order.Lazy.Internals
(OrderRep, emptyOrderRep)
import qualified Control.Monad.Trans.Order.Lazy.Internals
as Lazy
import Control.Monad.Trans.Order.Algorithm
import Control.Monad.Trans.Order.Algorithm.Type
-- Data
import Data.Functor.Identity
-- * The Order monad
type Order o = OrderT o Identity
evalOrder :: (forall o . Order o a) -> a
evalOrder order = runIdentity (evalOrderT order)
evalOrderWith :: Algorithm -> (forall o . Order o a) -> a
evalOrderWith alg order = runIdentity (evalOrderTWith alg order)
-- * The OrderT monad transformer
newtype OrderT o m a = OrderT (StateT (OrderRep o) m a) deriving (
Functor,
Applicative,
Alternative,
Monad,
MonadPlus,
MonadTrans,
MonadIO)
-- FIXME: Should we also have a MonadFix instance?
evalOrderT :: Monad m => (forall o . OrderT o m a) -> m a
evalOrderT = evalOrderTWith defaultAlgorithm
evalOrderTWith :: Monad m => Algorithm -> (forall o . OrderT o m a) -> m a
evalOrderTWith (Algorithm rawAlg) (OrderT stateT) = monad where
monad = evalStateT stateT (emptyOrderRep rawAlg)
force :: Monad m => OrderT o m ()
force = lazyToStrictOrderT Lazy.force
-- * Elements
newMinimum :: Monad m => OrderT o m (Element o)
newMinimum = lazyToStrictOrderT Lazy.newMinimum
newMaximum :: Monad m => OrderT o m (Element o)
newMaximum = lazyToStrictOrderT Lazy.newMaximum
newAfter :: Monad m => Element o -> OrderT o m (Element o)
newAfter = lazyToStrictOrderT . Lazy.newAfter
newBefore :: Monad m => Element o -> OrderT o m (Element o)
newBefore = lazyToStrictOrderT . Lazy.newBefore
-- * Converting between lazy and strict OrderT
lazyToStrictOrderT :: Lazy.OrderT o m a -> OrderT o m a
lazyToStrictOrderT (Lazy.OrderT (Lazy.StateT fun)) = OrderT (StateT fun)
strictToLazyOrderT :: OrderT o m a -> Lazy.OrderT o m a
strictToLazyOrderT (OrderT (StateT fun)) = Lazy.OrderT (Lazy.StateT fun)