{-# LANGUAGE CPP #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module ListT (
ListT(..),
runListT,
select,
fold
) where
import GhcPrelude
import Control.Applicative
import Control.Monad
import Control.Monad.Fail as MonadFail
newtype ListT m a =
ListT { unListT :: forall r. (a -> m r -> m r) -> m r -> m r }
select :: Monad m => [a] -> ListT m a
select xs = foldr (<|>) mzero (map pure xs)
fold :: ListT m a -> (a -> m r -> m r) -> m r -> m r
fold = runListT
runListT :: ListT m a -> (a -> m r -> m r) -> m r -> m r
runListT = unListT
instance Functor (ListT f) where
fmap f lt = ListT $ \sk fk -> unListT lt (sk . f) fk
instance Applicative (ListT f) where
pure a = ListT $ \sk fk -> sk a fk
f <*> a = ListT $ \sk fk -> unListT f (\g fk' -> unListT a (sk . g) fk') fk
instance Alternative (ListT f) where
empty = ListT $ \_ fk -> fk
f1 <|> f2 = ListT $ \sk fk -> unListT f1 sk (unListT f2 sk fk)
instance Monad (ListT m) where
m >>= f = ListT $ \sk fk -> unListT m (\a fk' -> unListT (f a) sk fk') fk
#if !MIN_VERSION_base(4,13,0)
fail = MonadFail.fail
#endif
instance MonadFail.MonadFail (ListT m) where
fail _ = ListT $ \_ fk -> fk
instance MonadPlus (ListT m) where
mzero = ListT $ \_ fk -> fk
m1 `mplus` m2 = ListT $ \sk fk -> unListT m1 sk (unListT m2 sk fk)