module Main (main) where import Control.Monad import Control.Monad.Reader import Control.Monad.State.Lazy import Control.Monad.Trans.Maybe import Data.Maybe (catMaybes) liftMaybeT :: Monad m => m a -> MaybeT m a liftMaybeT act = MaybeT $ Just `liftM` act type ResultM = MaybeT (State [()]) -- type ResultM = MaybeT (Reader [()]) runComputation :: ResultM a -> (Maybe a) runComputation r = (flip evalState $ [(), undefined]) . runMaybeT $ r -- runComputation r = (flip runReader $ [(), undefined]) . runMaybeT $ r runFunction :: ResultM () runFunction = do units <- get -- units <- ask units' <- liftMaybeT . fmap catMaybes . traverse runMaybeT $ fmap do_return units msum $ fmap (const $ return ()) units' where do_return () = return () main :: IO () main = do putStrLn "Running once" putStrLn . show . runComputation $ do runFunction putStrLn "Running twice" putStrLn . show . runComputation $ do runFunction runFunction putStrLn "Done" return ()