lhc-0.6.20081210.1: lib/base/src/Lhc/Monad.hs
{-# OPTIONS_LHC -N -funboxed-tuples #-}
module Lhc.Monad where
import Lhc.Basics
import Lhc.IO
-- Monadic classes
infixl 1 >>, >>=
infixr 1 =<<
class Functor f where
fmap :: (a -> b) -> f a -> f b
{- INLINE return, fail, (>>=), (>>) -}
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
-- Minimal complete definition:
-- (>>=), return
m >> k = m >>= \_ -> k
fail s = error s
{- SPECIALIZE sequence :: forall a . [IO a] -> IO [a] #-}
{- SPECIALIZE sequence_ :: forall a . [IO a] -> IO () #-}
{- SPECIALIZE mapM :: forall a b . (a -> IO b) -> [a]-> IO [b] #-}
{- SPECIALIZE mapM_ :: forall a b . (a -> IO b) -> [a]-> IO () #-}
{-# RULES "sequence/[]" sequence [] = return [] #-}
{-# RULES "sequence_/[]" sequence_ [] = return () #-}
{-# RULES "mapM/[]" forall f . mapM f [] = return [] #-}
{-# RULES "mapM_/[]" forall f . mapM_ f [] = return () #-}
{-# RULES "sequence_/++" forall xs ys . sequence_ (xs ++ ys) = sequence_ xs >> sequence_ ys #-}
{-# RULES "mapM_/++" forall xs ys f . mapM_ f (xs ++ ys) = mapM_ f xs >> mapM_ f ys #-}
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f as = go as where
go [] = return []
go (a:as) = do
a' <- f a
as' <- go as
return (a':as')
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
mapM_ f as = go as where
go [] = return ()
go (a:as) = f a >> go as
sequence :: Monad m => [m a] -> m [a]
sequence xs = f xs where
f [] = return []
f (x:xs) = x >>= \r -> f xs >>= \rs -> return (r:rs)
sequence_ :: Monad m => [m a] -> m ()
sequence_ xs = f xs where
f [] = return ()
f (x:xs) = x >> f xs
(=<<) :: Monad m => (a -> m b) -> m a -> m b
f =<< x = x >>= f
instance Monad [] where
return x = [x]
xs >>= f = concatMap f xs
fail _ = []
instance Functor [] where
fmap f (x:xs) = f x : fmap f xs
fmap f [] = []
instance Monad IO where
return x = IO $ \w -> (# w, x #)
IO x >>= f = IO $ \w -> case x w of
(# w, v #) -> case f v of
IO g -> g w
IO x >> IO y = IO $ \w -> case x w of
(# w, _ #) -> y w
fail s = ioError $ userError s
instance Functor IO where
fmap f a = a >>= \x -> return (f x)