module DeepControl.Monad.List (
ListT(..), mapListT, liftCallCC, liftCatch
) where
import DeepControl.Applicative
import DeepControl.Monad
import DeepControl.MonadTrans
import Control.Monad.Signatures
newtype ListT m a = ListT { runListT :: m [a] }
instance (Functor m) => Functor (ListT m) where
fmap f mv = ListT $ f |$>> runListT mv
instance (Applicative m) => Applicative (ListT m) where
pure = ListT . (**:)
f <*> v = ListT $ runListT f |*>> runListT v
instance (Monad m) => Monad (ListT m) where
return = pure
mv >>= f = ListT $
runListT mv >>== \v ->
runListT (f v)
instance MonadTrans ListT where
trans = ListT . (-*)
instance (MonadIO m) => MonadIO (ListT m) where
liftIO = trans . liftIO
mapListT :: (m [a] -> n [b]) -> ListT m a -> ListT n b
mapListT f = ListT . f . runListT
liftCallCC :: CallCC m [a] [b] -> CallCC (ListT m) a b
liftCallCC callCC f = ListT $
callCC $ \c ->
runListT $ (\a -> ListT $ c [a]) >- f
liftCatch :: Catch e m [a] -> Catch e (ListT m) a
liftCatch catchE m h = ListT $ runListT m `catchE` \e -> runListT (h e)