liveBook · Manning

mapM

As explained in Learn Haskell by Example

mapM is a standard Haskell function that applies an action-producing function to each element of a list, sequences the resulting actions, and collects their results in a list.

`mapM` maps an action-producing function across a collection, performs the resulting actions in order, and collects their results. For lists in `IO`, it is the action-based counterpart of `map`: where `map` computes pure results, `mapM` can actually run an action for every element. section 4.3.5

With `putStrLn`, each action returns `()`, so `mapM putStrLn` produces a list of units after printing. Choose `mapM_` instead when those collected results are useless: it performs the same actions but discards their outputs and returns one `()`. section 4.3.5 section 4.5

Printing every line

Applying `mapM putStrLn` to a list prints each string in sequence and returns `[(),(),()]`. The visible list is the collected return value of the individual printing actions, not additional output from `putStrLn`. section 4.3.5

ghci> mapM putStrLn ["Hello", "World", "!"]
Hello
World
!
[(),(),()]
ghci> mapM_ putStrLn ["Hello", "World", "!"]
Hello
World
!

Compare `mapM` and `mapM_` in GHCi: both print every string, but only `mapM` retains the list of action results. section 4.3.5

`mapM` also works beyond `IO`. Its general type uses a `Traversable` collection and a `Monad`: `(a -> m b) -> t a -> m (t b)`. In `Either String`, it transforms elements one by one and stops with the first `Left`, making it useful for validating parsed pixel data while preserving successful transformed values. section 13.2

Validation with Either

A function that rejects zero can be mapped over `[1..10]` to produce `Right [1,2,3,4,5,6,7,8,9,10]`. Mapping it over `[0..10]` produces `Left "zero is not allowed"`, because `Either` short-circuits when an element fails. section 13.2

How Learn Haskell by Example covers it

How deep it goes
Develops list-based IO behavior, then generalizes mapM to Traversable and Monad while noting its relationship to traverse.
Examples
Demonstrates printing strings with putStrLn and rejecting invalid values during Either-based pixel transformation.
What it assumes
Teaches action-based list mapping before later relying on Monad and Traversable constraints.
What you can do after
Apply it via mapM to run ordered IO actions or short-circuit Either validations across a collection.
How it connects
Connects mapM to map, mapM_, IO, unit, Either, Monad, Traversable, and traverse.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.