#if __GLASGOW_HASKELL__ >= 702
#endif
#if __GLASGOW_HASKELL__ >= 706
#endif
#if __GLASGOW_HASKELL__ >= 710
#endif
module Control.Monad.Trans.Select (
Select,
select,
runSelect,
SelectT(SelectT),
runSelectT,
selectToCont,
) where
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Trans.Cont
import Control.Applicative
import Control.Monad
#if MIN_VERSION_base(4,9,0)
import qualified Control.Monad.Fail as Fail
#endif
import Data.Functor.Identity
type Select r = SelectT r Identity
select :: ((a -> r) -> a) -> Select r a
select f = SelectT $ \ k -> Identity (f (runIdentity . k))
runSelect :: Select r a -> (a -> r) -> a
runSelect m k = runIdentity (runSelectT m (Identity . k))
newtype SelectT r m a = SelectT ((a -> m r) -> m a)
runSelectT :: SelectT r m a -> (a -> m r) -> m a
runSelectT (SelectT g) = g
instance (Functor m) => Functor (SelectT r m) where
fmap f (SelectT g) = SelectT (fmap f . g . (. f))
instance (Monad m) => Applicative (SelectT r m) where
pure = lift . pure
SelectT gf <*> SelectT gx = SelectT $ \ k -> do
let h f = liftM f (gx (k . f))
f <- gf ((>>= k) . h)
h f
instance (MonadPlus m) => Alternative (SelectT r m) where
empty = mzero
(<|>) = mplus
instance (Monad m) => Monad (SelectT r m) where
#if !(MIN_VERSION_base(4,8,0))
return = pure
#endif
SelectT g >>= f = SelectT $ \ k -> do
let h x = runSelectT (f x) k
y <- g ((>>= k) . h)
h y
#if MIN_VERSION_base(4,9,0)
instance (Fail.MonadFail m) => Fail.MonadFail (SelectT r m) where
fail msg = lift (Fail.fail msg)
#endif
instance (MonadPlus m) => MonadPlus (SelectT r m) where
mzero = SelectT (const mzero)
SelectT f `mplus` SelectT g = SelectT $ \ k -> f k `mplus` g k
instance MonadTrans (SelectT r) where
lift = SelectT . const
instance (MonadIO m) => MonadIO (SelectT r m) where
liftIO = lift . liftIO
selectToCont :: (Monad m) => SelectT r m a -> ContT r m a
selectToCont (SelectT g) = ContT $ \ k -> g k >>= k