Skip to content

Instantly share code, notes, and snippets.

@co-dan
Created December 13, 2012 08:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save co-dan/4275025 to your computer and use it in GitHub Desktop.
Save co-dan/4275025 to your computer and use it in GitHub Desktop.
Maybe monad transformer
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}
module MaybeT where
-- Maybe monad transformer
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance (Monad m) => Monad (MaybeT m) where
-- (>>=) :: (Monad m) => MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
x >>= f = MaybeT $
runMaybeT x >>= maybe (return Nothing) (runMaybeT . f)
-- return :: (Monad m) => a -> MaybeT m a
return x = MaybeT $ return (Just x)
instance MonadTrans MaybeT where
-- lift :: (Monad m) => m a -> MaybeT m a
lift = MaybeT . liftM Just
instance (MonadReader r m) => MonadReader r (MaybeT m) where
ask = lift ask
local f x = MaybeT $ local f (runMaybeT x)
instance (MonadWriter w m) => MonadWriter w (MaybeT m) where
tell = lift . tell
writer = lift . writer
listen x = MaybeT $ do
(result,log) <- listen (runMaybeT x)
case result of
Nothing -> return Nothing
Just v -> return $ Just (v,log)
pass x = MaybeT $ do
a <- runMaybeT x
case a of
Nothing -> return Nothing
Just (v,f) -> pass $ return (Just v,f)
instance (MonadState s m) => MonadState s (MaybeT m) where
put = lift . put
get = lift get
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment