Definition
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
x >> y = x >>= \_ -> y
fail :: String -> m a
fail msg = error msg
class Monad m => MonadPlus m where
mzero :: m a
mplus :: m a -> m a -> m a
Restriction
return x >>= f = f x
m >>= return = m
(m >>= f) >>= g = m >>= (\x -> f x >>= g)
Instances
.
(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = (\x -> f (g x))
(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = (\x -> g x >>= f)
Maybe
instance Monad Maybe where
return x = Just x
Nothing >>= f = Nothing
Just x >>= f = f x
fail _ = Nothing
List
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
instance MonadPlus [] where
mzero = []
mplus = (++)
guard :: (MonadPlus m) => Bool -> m ()
guard True :: return ()
guard False = mzero
Writer
newtype Writer w a = Writer { runWriter :: (a, w) }
instance (Monoid w) => Monad (Writer w) where
return x = Writer (x, mempty)
(Writer (x, v)) >>= f = let (Writer (y, v')) = f x
in Writer (y, v `mappend` v')
Reader/Function
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
State
State: s -> (a, s)
Stack
type Stack = [Int]
pop :: Stack -> (Int, Stack)
pop (x:xs) = (x, xs)
push :: Int -> Stack -> ((), Stack)
push a xs = ((), a:xs)
State
newtype State s a = State { runState :: s -> (a, s) }
instancce Monad (State s) where
return x = State $ \s -> (x, s)
(State h) >>= f = State $ \s -> let (a, newState) = h s
(State g) = f a
in g newState
pop :: State Stack Int
pop = state $ \(x:xs) -> (x, xs)
push :: Int -> State Stack ()
push a = state $ \xs -> ((), a:xs)
Get/Set
get = state $ \s -> (s, s)
put newState = state $ \s -> ((), newState)
Error
instance (Error e) => Monad (Either e) where
return x = Right x
Right x >>= f = f x
Left err >>= f = Left err
fail msg = Left (strMsg msg)
Monadic
liftM
liftM :: (Monad m) => (a -> b) -> m a -> m b
liftM f m = m >>= (\x -> return (f x))
liftM f m = do
x <- m
return (f x)
liftM2 :: (Monad f) => (a -> b -> c) -> f a -> f b -> f c
join
join :: (Monad m) => m (m a) -> m a
join mm = do
m <- mm
m
filterM
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
foldM
foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a