| module: | Prelude |
| type: | (=<<) :: Monad m => (a -> m b) -> m a -> m b |
| description: |
This is the "reverse binder" function; the expression
f =<< mtakes the contents of monad m and passes it to function f as a parameter. It may be useful when used as a parameter of a higher order function, or one can use it as a more readable way of coding, in some cases. |
| definition: |
infixr 1 =<<
f =<< x = x >>= f
|
| usage: |
> replicate 2 =<< [1, 2, 3]
[1,1,2,2,3,3]
|
| see also: |
(>>=), (>>) |
| module: | Prelude |
| type: | (>>) :: m a -> m b -> m b |
| description: | This operator is essentially the same as (>>=), but does not pass the contents of the monad to the function specified as second parameter. It can be used to define the order in which actions take place. |
| definition: |
infixl 1 >>
m >> k = m >>= \_ -> k
|
| usage: |
> putStrLn "asd" >> putStrLn "qwerty"
asd
qwerty
|
| see also: |
(>>=), (=<<) |
| module: | Prelude |
| type: | (>>=) :: m a -> (a -> m b) -> m b |
| description: |
This is the "bind" function; the expression
m >>= ftakes the contents of monad m and passes it to function f as a parameter. >>= is one of the two basic operators of the Monad class (the other is return). Any instantiation of >>= and return must obey the following laws: return a >>= k = k a m >>= return = m m >>= (\x -> k x >>= h) = (m >>= k) >>= hSometimes a fourth law is mentioned, but not everybody agrees with this one: xs >>= return . f = fmap f xs |
| definition: |
infixl 1 >>=
instance Monad Maybe where
(Just x) >>= k = k x
Nothing >>= k = Nothing
instance Monad IO where
(>>=) = ... -- No Haskell representation possible.
instance Monad [] where
m >>= k = concat (map k m)
|
| usage: |
> Just 3 >>= Just
Just 3
> Just 3 >>= return
Just 3
> getLine >>= print . tail
nice
"ice"
|
| see also: |
(>>), (=<<) |
| module: | Control.Monad |
| type: | ap :: (Monad m) => m (a -> b) -> m a -> m b |
| description: |
ap applies a function inside a monad to a value
inside a monad of the same type.
A call to liftMn can often be replaced by one or more
calls to ap:
return f `ap` x1 `ap` ... `ap` xnis the same as: liftMn f x1 x2 ... xn |
| definition: |
ap = liftM2 ($)
|
| usage: |
Apply a list of functions to a list of values:
> [(+ 1), (+ 2)] `ap` [1, 2, 3]
[2, 3, 4, 3, 4, 5]
Apply a function in the Maybe monad to a value
in the Maybe monad:
> Just (+ 1) `ap` Just 1
Just 2
Apply a function, with two parameters, in the
Maybe monad, to two values in the Maybe monad:
> Just (*) `ap` (Just 2) `ap` (Just 3)
Just 6
> return cos `ap` Just pi
Just (-1.0)
|
| see also: |
liftM2, liftM3, liftM4, liftM5 |
| module: | Prelude |
| type: | fail :: String -> m a |
| description: | fail is to be called in case a certain condition is not met. When using the IO () version of fail, the program is interrupted; in other monads, the effect is less drastic; the list version, for example, returns an empty list. |
| definition: |
class Monad m where
fail s = error s
instance Monad Maybe where
fail s = Nothing
instance Monad IO where
fail s = ioError (userError s)
instance Monad [] where
fail s = []
|
| usage: |
> fail "Cannot do that" :: Maybe Int
Nothing
> fail "Cannot do that" :: [Int]
[]
> fail "Cannot do that" :: IO ()
Program error: user error (Cannot do that)
> if 'a' == 'b' then [333] else fail "'a' is not 'b'"
[]
-- Begin source code --
{-
Read a list of sublists, and return a list containing the sums
of only those sublists with exactly two elements, while
ignoring the rest of the sublists.
-}
f :: Num a => [[a]] -> [a]
f xs =
do
[x, y] <- xs
return (x + y)
-- End source code --
> f [[1, 2], [3], [4, 5]]
[3, 9]
|
| see also: |
error, ioError, userError |
| module: | Control.Monad |
| type: | filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] |
| description: | filterM p xs filters out all elements of xs that do not fulfill the predicate p, where p is a function that returns a value of type Monad m => m Bool; the result is a list inside a monad of the same type. |
| definition: |
filterM p [] = return []
filterM p (x : xs) =
do
b <- p x
ys <- filterM p xs
return (if b then (x : ys) else ys)
|
| usage: |
> filterM (\x -> Just (x > 0)) [2, 1, 0, -1]
Just [2, 1]
> filterM (\x -> [x > 0]) [2, 1, 0, -1]
[[2, 1]]
|
| see also: |
filter |
| module: | Prelude |
| type: | fmap :: Functor f => (a -> b) -> f a -> f b |
| description: |
fmap f x lets function f operate on
x, even though x has a different type
then f was designed for. fmap is
defined for the types Maybe, IO and
[] in Prelude. In case of lists,
fmap behaves exactly like map and
liftM; in case of the Maybe monad, fmap
behaves like liftM.
Every instance of fmap should satisfy the following laws:
fmap id = id fmap (f . g) = fmap f . fmap g |
| definition: |
In module Control.Monad:
instance Functor Maybe where
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
instance Functor IO where
fmap f x = x >>= (return . f)
instance Functor [] where
fmap = map
In module Data.Array:
instance (Ix a) => Functor (Array a) where
fmap fn (MkArray b f) = MkArray b (fn . f)
In modules Control.Monad.ST.Lazy and Control.Monad.ST:
instance Functor (ST s) where
fmap = liftM
Other modules with definitions exist.
|
| usage: |
Apply "negate" to a value in a Maybe monad:
> fmap negate (Just 1)
Just (-1)
Take the square root of all elements in a list:
> fmap sqrt [1.0, 4.0, 9.0]
[1.0, 2.0, 3.0]
Increment a value in a Maybe monad:
> let inc = fmap (+ 1) in inc (Just 2)
Just 3
Increment a value in a Maybe monad, using liftM:
> let inc = liftM (+ 1) in inc (Just 2)
Just 3
Increment all elements in a list:
> let inc = fmap (+ 1) in inc [2, 3]
[3, 4]
Convert input to uppercase:
> putStr =<< fmap (fmap toUpper) getLine
asdf
ASDF
|
| see also: |
map, liftM |
| module: | Control.Monad |
| type: | foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a |
| description: |
foldM is the monadic version of foldl,
whereas foldl takes a function of type
a -> b -> afoldM takes a function of type: (Monad m) => (a -> b -> m a)In different words, it takes a function with two non-monadic parameters, resulting in a monadic value and folds a list with it. The expression: foldM f a [x1, x2, ..., xn]is equal to: f (... f (f (f a x1) x2 ...) xnThe equivalent of foldr can be achieved by: foldrM f a xs = foldM f a (reverse xs) |
| definition: |
foldM f a [] = return a
foldM f a (x : xs) = f a x >>= \ y -> foldM f y xs
|
| usage: |
-- Begin source code --
{-
Create a function that divides by a list of numbers,
similar to "sum" and "product"
-}
import Data.Maybe
import Control.Monad
-- A function that takes care of the "divide by zero" problem
(./.) :: Fractional a => a -> a -> Maybe a
x ./. 0 = Nothing
x ./. y = Just (x / y)
divide :: Fractional a => a -> [a] -> Maybe a
divide x ys = foldM (./.) x ys
-- End source code --
> divide 1 [2, 3]
Just 0.166666666666667
|
| see also: |
foldl, foldr |
| module: | Control.Monad |
| type: | guard :: MonadPlus m => Bool -> m () |
| description: |
guard p returns ()
if p is True,
otherwise mzero; it can be used as follows:
myDiv :: Fractional a => a -> a -> Maybe a
myDiv x y =
do
guard (y /= 0)
return (x / y)
Or:
myDiv :: Fractional a => a -> a -> Maybe a myDiv x y = guard (y /= 0) >> return (x / y)When y == 0, The function returns Nothing, otherwise Just (x / y). |
| definition: |
guard p = if p then return () else mzero
|
| usage: |
> :l Monad
> guard True >> Just 3
Just 3
> guard False >> Just 3
Nothing
> guard True >> [1, 2, 3]
[1,2,3]
> guard False >> [1, 2, 3]
[]
> myDiv 1 0
Nothing
> myDiv 1 1
Just 1.0
> :a Control.Monad.Error
> guard True >> print "OK"
"OK"
> guard False >> print "OK"
Program error: user error (mzero)
|
| see also: |
mzero, when, unless |
| module: | Control.Monad |
| type: | join :: (Monad m) => m (m a) -> m a |
| description: | join removes one layer of nesting of a monadic value: join (m (m x)) changes m (m x) to m x |
| definition: |
join x = x >>= id
|
| usage: |
> join (Just (Just 1))
Just 1
|
| see also: |
|
| module: | Control.Monad |
| type: | liftM :: (Monad m) => (a -> b) -> (m a -> m b) |
| description: | liftM f m lets a non-monadic function f operate on the contents of monad m |
| definition: |
liftM f = \a -> do { a' <- a; return (f a') }
|
| usage: |
> liftM sin (Just 0)
Just 0.0
> liftM (replicate 10) ['a']
["aaaaaaaaaa"]
|
| see also: |
fmap, liftM2, liftM3, liftM4, liftM5 |
| module: | Control.Monad |
| type: | liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c) |
| description: | liftM2 f m1 m2 lets a non-monadic function f operate on the contents of monads m1 and m2 |
| definition: |
liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') }
|
| usage: |
-- Create the new operator ?- to subtract
-- numbers encapsulated in monads:
> let (?-) = liftM2 (-) in Just 3 ?- (Just 2)
Just 1
-- Create the new operator ?* to multiply
-- numbers encapsulated in monads,
-- multiply with "Nothing":
> let (?*) = liftM2 (*) in Just 3 ?* Nothing
Nothing
|
| see also: |
liftM, liftM3, liftM4, liftM5, fmap |
| module: | Control.Monad |
| type: | liftM3 :: (Monad m) => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d) |
| description: | liftM3 f m1 m2 m3 lets a non-monadic function f operate on the contents of monads m1, m2 and m3 |
| definition: |
liftM3 f = \a b c -> do { a' <- a
; b' <- b
; c' <- c
; return (f a' b' c')
}
|
| usage: |
> liftM3 flip (Just elem) (Just [1..10]) (Just 5)
Just True
|
| see also: |
liftM, liftM2, liftM4, liftM5, fmap |
| module: | Control.Monad |
| type: | liftM4 :: (Monad m) => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e) |
| description: | liftM4 f m1 m2 m3 m4 lets a non-monadic function f operate on the contents of monads m1, m2, m3 and m4 |
| definition: |
liftM4 f = \a b c d -> do { a' <- a
; b' <- b
; c' <- c
; d' <- d
; return (f a' b' c' d')
}
|
| usage: |
> let sum4 w x y z = w + x + y + z in liftM4 sum4 (Just 0) (Just 1) (Just 2) (Just 3)
Just 6
|
| see also: |
liftM, liftM2, liftM3, liftM5, fmap |
| module: | Control.Monad |
| type: | liftM5 :: (Monad m) => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f) |
| description: | liftM5 f m1 m2 m3 m4 m5 lets a non-monadic function f operate on the contents of monads m1, m2, m3, m4 and m5 |
| definition: |
liftM5 f = \a b c d e -> do { a' <- a
; b' <- b
; c' <- c
; d' <- d
; e' <- e
; return (f a' b' c' d' e')
}
|
| usage: |
> let sum5 v w x y z = v + w + x + y + z in liftM5 sum5 (Just 0) (Just 1) (Just 2) (Just 3) (Just 4)
Just 10
|
| see also: |
liftM, liftM2, liftM3, liftM4, fmap |
| module: | Control.Monad |
| type: | mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c]) |
| description: | mapAndUnzipM mf xs takes a monadic function mf (having type (Monad m) => (a -> m (b,c))) and applies it to each element in list xs; the resulting list of two-tuples is then unzipped, the final result is a two-tuple of lists inside a monad. |
| definition: |
mapAndUnzipM f xs = sequence (map f xs) >>= return . unzip
|
| usage: |
> map (divMod 3) [1, 2, 3, 4, 5]
[(3,0),(1,1),(1,0),(0,3),(0,3)]
> unzip (map (divMod 3) [1, 2, 3, 4, 5])
([3,1,1,0,0],[0,1,0,3,3])
> mapAndUnzipM (Just . divMod 3) [1, 2, 3, 4, 5]
Just ([3,1,1,0,0],[0,1,0,3,3])
|
| see also: |
map, unzip |
| module: | Prelude |
| type: | mapM :: Monad m => (a -> m b) -> [a] -> m [b] |
| description: |
mapM mf xs takes a monadic function
mf (having type
Monad m => (a -> m b))
and applies it to each element in list
xs; the result is a list inside a monad.
The difference between mapM and mapM_ is, that mapM returns a list of the results, while mapM_ returns an empty result. |
| definition: |
mapM f as = sequence (map f as)
|
| usage: |
> mapM Just [0, 1, 2]
Just [0,1,2]
> mapM print [0, 1, 2]
0
1
2
> mapM (\x -> [x]) [0, 1, 2]
[[0,1,2]]
|
| see also: |
map, mapM_, sequence |
| module: | Prelude |
| type: | mapM_ :: Monad m => (a -> m b) -> [a] -> m () |
| description: |
mapM_ mf xs takes a monadic function
mf (having type
Monad m => (a -> m b))
and applies it to each element in list
xs; the result of each action is not stored.
The difference between mapM and mapM_ is, that mapM returns a list of the results, while mapM_ returns an empty result. |
| definition: |
mapM_ f as = sequence_ (map f as)
|
| usage: |
> mapM_ Just [0, 1, 2]
Just ()
> mapM_ print [0, 1, 2]
0
1
2
> mapM_ (\x -> [x]) [0, 1, 2]
[()]
|
| see also: |
map, mapM, sequence |
| module: | Control.Monad |
| type: | mplus :: MonadPlus a => a b -> a b -> a b |
| description: |
The method mplus is the plus of the MonadPlus class.
Any definition of mplus must obey the following laws:
m `mplus` mzero = m mzero `mplus` m = m |
| definition: |
class Monad m => MonadPlus m where
mplus :: m a -> m a -> m a
instance MonadPlus Maybe where
Nothing `mplus` ys = ys
xs `mplus` ys = xs
instance MonadPlus [] where
mplus = (++)
-- Other instances can be found in other modules
|
| usage: |
> "a" `mplus` "b"
"ab"
> Just "a" `mplus` Just "b"
Just "a"
> Nothing `mplus` Just "b"
Just "b"
> undefined `mplus` Just 2
Program error: Prelude.undefined
> Just 1 `mplus` undefined
Just 1
|
| see also: |
mzero, msum |
| module: | Control.Monad |
| type: | msum :: MonadPlus m => [m a] -> m a |
| description: | msum is the monadic version of sum, it sums the elements of a list with mplus, using mzero as a starting value. |
| definition: |
msum xs = foldr mplus mzero xs
|
| usage: |
> msum ["a", "b", "c"]
"abc"
> msum [Just "a", Just "b", Just "c"]
Just "a"
> msum [Nothing, Just "b", Just "c"]
Just "b"
|
| see also: |
mplus, mzero, foldr |
| module: | Control.Monad |
| type: | mzero :: MonadPlus m => m a |
| description: |
mzero is the zero of the MonadPlus class.
Any definition of mzero must obey the following laws:
m >>= \x -> mzero = mzero mzero >>= m = mzero |
| definition: |
class Monad m => MonadPlus m where
mzero :: m a
instance MonadPlus Maybe where
mzero = Nothing
instance MonadPlus [] where
mzero = []
-- Other instances may be found in other modules
|
| usage: |
> mzero :: [Int]
[]
> mzero :: Maybe Int
Nothing
> (mzero :: Maybe Int) >>= \x -> Just (x * x)
Nothing
> Just 1 `mplus` mzero
Just 1
> mzero `mplus` Just 2
Just 2
> mzero `mplus` [1]
[1]
|
| see also: |
mplus, msum |
| module: | Prelude |
| type: | return :: Monad m => a -> m a |
| description: |
return is one of the two basic operators of the
Monad class (the other is >>= (called "bind")).
One could say, it converts a value to a monad containing this value;
the type of this monad depends on the type of the expression.
Any instantiation of >>= and return must obey the laws mentioned at the desciption of (>>=) |
| definition: |
class Monad m where
return :: a -> m a
instance Monad Maybe where
return = Just
instance Monad IO where
return = ... -- This cannot be expressed in Haskell
instance Monad [] where
return x = [x]
|
| usage: |
> (return 3) :: Maybe Int
Just 3
> (return 3) :: [Int]
[3]
> getLine >>= \x -> return (x ++ x) >>= print
haha
"hahahaha"
> do {x <- getLine; y <- return (x ++ x); print y}
qwerty
"qwertyqwerty"
|
| see also: |
(>>=) |
| module: | Prelude |
| type: | sequence :: Monad m => [m a] -> m [a] |
| description: |
sequence xs evaluates all monadic
values in the list xs,
from left to right, and returns a list of the "contents" of
these monads, placing this list in a monad of the same type.
Note, that "evaluating" can be interpreted as "performing an
action", for example in the case of print.
The difference between sequence and sequence_ is that sequence returns a list of the results, while sequence_ returns an empty result. |
| definition: |
sequence = foldr mcons (return [])
where
mcons p q = p >>= \x -> q >>= \y -> return (x : y)
|
| usage: |
> sequence [print 1, print 2, print 3]
1
2
3
> sequence [print 1, print 2, print 3] >>= print
1
2
3
[(),(),()]
> sequence [Just 1, Just 2, Just 3]
Just [1,2,3]
|
| see also: |
sequence_ |
| module: | Prelude |
| type: | sequence_ :: Monad m => [m a] -> m () |
| description: |
sequence_ xs evaluates all monadic
values in the list xs,
from left to right, and returns () inside a monad.
Note, that "evaluating" can be read as "performing an action".
The difference between sequence and sequence_ is that sequence returns a list of the results, while sequence_ returns an empty result. |
| definition: |
sequence_ = foldr (>>) (return ())
|
| usage: |
> sequence_ [print 1, print 2, print 3]
1
2
3
> sequence_ [print 1, print 2, print 3] >>= print
1
2
3
()
> sequence_ [Just 1, Just 2, Just 3]
Just ()
|
| see also: |
sequence |
| module: | Control.Monad |
| type: | unless :: (Monad m) => Bool -> m () -> m () |
| description: | unless p me executes monadic expression me when p is False. |
| definition: |
unless p s = when (not p) s
|
| usage: |
> unless (0 == 1) (print "OK")
"OK"
> unless (1 == 1) (print "This is the end of logic")
> let simulation = True in unless simulation (putStrLn "Launching Ariane 5 now")
|
| see also: |
when, guard |
| module: | Control.Monad |
| type: | when :: (Monad m) => Bool -> m () -> m () |
| description: | when p me executes monadic expression me when p is True. |
| definition: |
when p s = if p then s else return ()
|
| usage: |
> when (1 == 1) (print "OK")
"OK"
> when (0 == 1) (print "This is the end of logic")
|
| see also: |
unless, guard |
| module: | Control.Monad |
| type: | zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c] |
| description: | zipWithM if the monadic version of zipWith; zipWithM me xs ys uses monadic expression me to zip the lists xs and ys. |
| definition: |
zipWithM f xs ys = sequence (zipWith f xs ys)
|
| usage: |
> zipWithM (\x y -> Just (x + y)) [1, 2, 3] [4, 5, 6]
Just [5,7,9]
> zipWithM (\x y -> print (x + y)) [1, 2, 3] [4, 5, 6]
5
7
9
> zipWithM (\x y -> print (x + y)) [1, 2, 3] [4, 5, 6] >>= print
5
7
9
[(),(),()]
|
| see also: |
zipWithM_, zipWith |
| module: | Control.Monad |
| type: | zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m () |
| description: | zipWithM_ if the monadic version of zipWith; zipWithM_ me xs ys uses monadic expression me to zip the lists xs and ys; it returns m (), where m is a monad of the same type as the result of me. |
| definition: |
zipWithM_ f xs ys = sequence_ (zipWith f xs ys)
|
| usage: |
> zipWithM_ (\x y -> Just (x + y)) [1, 2, 3] [4, 5, 6]
Just ()
> zipWithM_ (\x y -> print (x + y)) [1, 2, 3] [4, 5, 6]
5
7
9
> zipWithM_ (\x y -> print (x + y)) [1, 2, 3] [4, 5, 6] >>= print
5
7
9
()
|
| see also: |
zipWithM, zipWith |