What is the difference between mapM_ and mapM in Haskell?

后端 未结 4 425
野的像风
野的像风 2021-02-01 16:25

I\'ve already checked Hoogle, http://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#v:mapM, which says that mapM_ ignores the results.

However,

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-01 17:18

    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 m [b]. mapM_ does the same thing, but never collects the results, returning a m ().

    If you care about the results of your a -> m b function (ie the bs), use 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 print or putStrLn. These functions return () to signify that only the effect matters. If you used mapM, you'd get a list of () (ie [(), (), ()]), 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.

    So: mapM if you care about the results and mapM_ if you don't.

    Normal 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 map.

提交回复
热议问题