module NonDetMT (WithNonDet, removeNonDet) where
import Tree
import Monad
import MT
import Control_Monad_Fix
newtype WithNonDet m a = ND { removeNonDet :: m (Tree a) }
instance Monad m => Functor (WithNonDet m) where
fmap = liftM
instance Monad m => Monad (WithNonDet m) where
return x = ND (return (return x))
ND m >>= f = ND (liftM join . Tree.mapM (removeNonDet . f) =<< m)
instance MT WithNonDet where
lift m = ND (liftM return m)
instance Monad m => MonadPlus (WithNonDet m) where
mzero = ND (return mzero)
mplus (ND x) (ND y) = ND (liftM2 mplus x y)
instance HasEnv m ix e => HasEnv (WithNonDet m) ix e where
getEnv = lift . getEnv
inModEnv ix f (ND m) = ND (inModEnv ix f m)
instance HasState m ix s => HasState (WithNonDet m) ix s where
updSt ix = lift . updSt ix
instance HasOutput m ix o => HasOutput (WithNonDet m) ix o where
outputTree ix = lift . outputTree ix
instance HasExcept m x => HasExcept (WithNonDet m) x where
raise = lift . raise
handle h (ND m) = ND (handle (removeNonDet . h) m)
instance HasCont m => HasCont (WithNonDet m) where
callcc f = ND $ callcc $ \k -> removeNonDet $ f $ ND . k . return
instance HasBaseMonad m n => HasBaseMonad (WithNonDet m) n where
inBase = lift . inBase
instance HasRefs m r => HasRefs (WithNonDet m) r where
newRef = lift . newRef
readRef = lift . readRef
writeRef r = lift . writeRef r
instance MonadFix m => MonadFix (WithNonDet m) where
mfix f = ND $ do res <- mfix (removeNonDet . f . theSingle)
case res of
Node _ _ -> do l <- removeNonDet $ mfix (ND . liftM theLeft . removeNonDet . f)
r <- removeNonDet $ mfix (ND . liftM theRight . removeNonDet . f)
return (Node l r)
_ -> return res