1 module Control.Monad.X.NondetT
11 import Monad(liftM,MonadPlus(..))
13 import Control.Monad.X.Trans as T
14 import Control.Monad.X.Utils
15 import Control.Monad.X.Types(NondetT(..),T(..))
18 instance MonadTrans NondetT where
19 lift m = N (liftM single m)
21 instance Monad m => Functor (NondetT m) where
24 instance Monad m => Monad (NondetT m) where
26 m >>= f = N (do x <- unN m
29 Cons a xs -> unN (mplus (f a) (xs >>= f)))
31 instance HasBaseMonad m n => HasBaseMonad (NondetT m) n where
36 instance Monad m => Functor (T m) where
38 fmap f (Cons a m) = Cons (f a) (fmap f m)
41 single x = Cons x mzero
43 flatten :: Monad m => T m a -> m [a]
44 flatten Empty = return []
45 flatten (Cons a m) = liftM (a :) (runNondets m)
48 runNondet m = do t <- unN m
50 Empty -> return Nothing
51 Cons a _ -> return (Just a)
53 runNondets m = flatten =<< unN m
55 mapNondetT f (N m) = N (f m)
60 instance MonadReader r m => MonadReader r (NondetT m) where
62 local = local' mapNondetT
64 instance MonadWriter w m => MonadWriter w (NondetT m) where
66 listen = listen1' N unN (\w -> fmap (\a -> (a,w)))
68 instance MonadState s m => MonadState s (NondetT m) where
72 instance MonadError e m => MonadError e (NondetT m) where
73 throwError = throwError'
74 catchError = catchError1' N unN
76 instance Monad m => MonadPlus (NondetT m) where
77 mzero = N (return Empty)
78 mplus m n = N (do x <- unN m
81 Cons a m' -> return (Cons a (mplus m' n)))
83 instance Monad m => MonadNondet (NondetT m) where
84 findAll m = lift (runNondets m)
85 commit m = N (do x <- unN m
88 Cons a _ -> return (single a))
90 -- ergh, what does this do?
91 instance (MonadCont m) => MonadCont (NondetT m) where
92 callCC = callCC1' N unN single