Traversable

Contents
traverse
sequence
Effects in order
for and mapM

traverse

traverse maps a function that returns a context and flips the two layers. A list of Maybe becomes a Maybe of a list:

traverse :: Applicative f => (a -> f b) -> [a] -> f [b] traverse (\x -> if x > 0 then Just x else Nothing) [1,2,3] -- Just [1,2,3] traverse (\x -> if x > 0 then Just x else Nothing) [1,-2,3] -- Nothing

One failure anywhere makes the whole result fail, and the error is the first one encountered. That is exactly the behaviour of a chain of >>=, written once for the whole list.

sequence

When the list already holds the contexts, sequence does the flipping without a function. It is traverse id:

sequence [Just 1, Just 2, Just 3] -- Just [1,2,3] sequence [Just 1, Nothing, Just 3] -- Nothing sequence [[1,2], [3,4]] -- four combinations

The list instance produces the cartesian product, which is the same behaviour that made <*> surprising in lesson 30.

Effects in order

In IO, traversal is how a program runs an action per element and keeps the results. The order is the order of the list:

readAll :: [FilePath] -> IO [String] readAll = traverse readFile main = do texts <- readAll ["a.txt", "b.txt"] putStrLn (show (map length texts))

traverse over IO runs the effects left to right and collects the values. Nothing is parallel, and nothing is skipped on failure, because IO has no short-circuit.

for and mapM

Two aliases make the same function read better. for flips the arguments so the body comes last, and mapM is the monadic name you will see in older code:

for [1,2,3] \x -> do putStrLn (show x) pure (x * 2) mapM print [1,2,3] -- the same as traverse print

Use for when the body is a block and traverse when it is a single expression. Both do the same work, and the compiler treats them identically.

Next: Monad transformers

Article author: Arthur Isaev

Related articles
Haskell
Haskell course: zero to hero in 50 lessons
What is Haskell and why it matters
Install the toolchain with GHCup
GHCi: the interactive shell
Your first program
Values with let and where
Types and type signatures
Functions and application
Currying and partial application
Operators, sections, and fixity
if, guards, and pattern guards
case expressions
Pattern matching
Tuples
Lists
Ranges and enumeration
List comprehensions
Recursion replaces loops
map, filter, and foldr
Lambdas and composition
Type classes
Parametric polymorphism
Maybe and null safety
Either and recoverable errors
data: product types
data: sum types
Records
newtype and type synonyms
Recursive data: binary trees
Functor
Applicative
Monad
do notation
IO and purity
Files and IO
Modules and imports
Cabal projects
Dependencies
Testing with HUnit
Property testing with QuickCheck
Laziness and infinite lists
Strictness and space leaks
Folds
Monoids
Traversable
Monad transformers
Errors and exceptions
Concurrency
Parsing with Megaparsec
Capstone: a todo CLI
Hero roadmap: the whole course on one page

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: