I've already checked hoogle, http://hackage.haskell.org/package/base-22.214.171.124/docs/Prelude.html#v:mapM
mapM_ ignore the results.
But I still don't have idea how to user properly.
main = mapM_ (putStrLn.show) [1,2]
main = mapM (putStrLn.show) [1,2]
main = map (putStrLn.show) [1,2]
mapM_ is useful for executing something only for its side effects. For example, printing a string to standard output doesn't return anything useful - it returns
(). If we have a list of three strings, we would end up accumulating a list
[(), (), ()]. Building this list has a runtime cost, both in terms of speed and memory usage, so by using
mapM_ we can skip this step entirely.
However, sometimes we need to execute side effects and build up a list of the results. If we have a function such as
lookupUserById :: UserId -> IO User
Then we can use this to inflate a list of
UserIds to a list of
lookupUsers :: [UserId] -> IO [User] lookupUsers = mapM lookupUserById
The core idea is that
mapM maps an "action" (ie function of type
a -> m b) over a list and gives you all the results as a
mapM_ does the same thing, but never collects the results, returning a
If you care about the results of your
a -> m b function (ie the
mapM. If you only care about the effect, whatever it is, but not the resulting value, use
mapM_ because it can be more efficient and, more importantly, makes your intentions clear.
You would always use
mapM_ with functions of the type
a -> m (), like
putStrLn. These functions return
() to signify that only the effect matters. If you used
mapM, you'd get a list of
[(), (), ()]), which would be completely useless but waste some memory. If you use
mapM_, you would just get a
(), but it would still print everything.
On the other hand, if you do care about the returned values, use
mapM. As a hypothetical example, imagine a function
fetchUrl :: Url -> IO Response—chances are, you care about the response you get for each URL. So for this, you'd use
mapM to get a lists of responses out that you can then use in the rest of your code.
mapM if you care about the results and
mapM_ if you don't.
map is something different: it takes a normal function (
a -> b) instead of one using a monad (
a -> m b). This means that it cannot have any sort of effect besides returning the changed list. You would use it if you want to transform a list using a normal function.
map_ doesn't exist because, since you don't have any effects, you always care about the results of using
In more general terms, the difference is that
mapM_ only needs to "consume" all elements of the input, whereas
mapM also needs to "re-build" the data structure, with new values. That's pretty much trivial for lists: you only need to traverse along the cons-cells, updating values with those received from the action you map. But it doesn't work that easily for containers whose structure depends on the actual contained values. So e.g. for
Data.Set you can't define the equivalent of
mapM with type
(a -> m b) -> Set a -> m (Set b) – it is an instance of
Foldable, but not of
mapM_ ignores the result. This means, that no return value will be returned. You can see this in interactive mode:
$ ghci GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> mapM (putStrLn . show ) [1,2] 1 2 [(),()] Prelude> mapM_ (putStrLn . show ) [1,2] 1 2