HASKELL / CHAPTER 10
Traverse collections of checked results
AdvancedTurn many small validations into one structured outcome.
By the end of this chapter
- Distinguish map from traverse
- Preserve collection shape on success
- Explain short-circuit failure behavior
The idea
Mapping a checked function over a list produces a list of checked results, such as [Maybe Int]. Sometimes a caller instead needs one result describing the entire operation: Maybe [Int], where success contains every value and failure means at least one item failed. Traverse combines the traversal with the effect represented by the result type.
The effect determines the failure policy. Ordinary Maybe and Either traversals stop producing a successful whole result when an item fails; standard Either does not automatically collect all validation errors. Choose an accumulating validation design when every error must be reported. Keep input order and output shape explicit, and test an empty list, an all-success list, and a failure in the middle.
import Text.Read (readMaybe)
parseAll :: [String] -> Maybe [Int]
parseAll = traverse readMaybe
main = do
print (parseAll ["2","5"])
print (parseAll ["2","bad","5"])Just [2,5] Nothing
Traverse collects successful parses inside one Maybe. A failed parse prevents a successful complete list.
Try it yourself
Validate a list with Either and document whether the API needs first-error or all-errors reporting.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING