Converting List Maybe a to Maybe List a in Elm
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Converting List (Maybe a) to Maybe (List a) is a common operation in functional programming called sequence. It takes a list of optional values and returns Nothing if any value is Nothing, or Just of the complete list if all values are Just. Elm does not include sequence in its core library, but it can be implemented with List.foldr or by using packages like elm-community/maybe-extra.
The Transformation
If every element is Just, unwrap them all into a single Just list. If any element is Nothing, the entire result is Nothing. This is an all-or-nothing operation.
Implementation with foldr
How it works:
- Start with
Just []as the accumulator - For each element, if both the element and accumulator are
Just, prepend the unwrapped value - If either is
Nothing, the result becomesNothingand staysNothing
Usage Examples
Implementation with Maybe.andThen
This version uses Maybe.andThen (equivalent to >>= or bind in Haskell) and Maybe.map instead of explicit pattern matching.
Traverse: Map and Sequence in One Step
traverse applies a function that returns Maybe to each element, then sequences the result. It is more efficient than List.map f >> sequence because it combines both operations:
Keeping Only Just Values (Alternative)
If you want to keep the Just values and discard Nothing instead of failing entirely:
Use sequence when all values must be present (validation, parsing). Use List.filterMap when missing values are acceptable.
Practical Example: Form Validation
Comparison with Haskell and Other Languages
Elm does not have type classes, so sequence must be implemented specifically for each wrapper type (Maybe, Result, etc.) rather than generically.
Common Pitfalls
- Using List.filterMap when sequence is needed:
List.filterMap identitysilently dropsNothingvalues. If you need to know whether all values were present (e.g., form validation), usesequencewhich returnsNothingwhen any value is missing. - Performance with large lists: The
foldr-basedsequenceprocesses the entire list even if the first element isNothing. For large lists where early failure is common, consider a recursive implementation that short-circuits on the firstNothing. - Confusing sequence with traverse:
sequenceunwraps aList (Maybe a)intoMaybe (List a).traverse fmaps a functiona -> Maybe bover a list and then sequences. Usetraversewhen you need both operations — it avoids creating an intermediateList (Maybe b). - Forgetting the empty list case:
sequence []returnsJust [], notNothing. This is the correct mathematical behavior (vacuous truth), but it can be surprising in validation contexts where an empty input might be considered invalid. - Not using elm-community/maybe-extra: The
Maybe.Extrapackage providescombine(equivalent tosequence),traverse, and other utilities. Installing it avoids reimplementing these functions and provides well-tested, optimized versions.
Summary
sequenceconvertsList (Maybe a)toMaybe (List a)— returnsNothingif any element isNothing- Implement with
List.foldrand pattern matching on(maybeElem, acc) traversecombines mapping and sequencing in one pass for better efficiency- Use
List.filterMap identitywhen you want to discardNothingvalues instead of failing - The
elm-community/maybe-extrapackage providescombine(sequence) andtraverseready to use sequence []returnsJust [](empty list is valid) — add an explicit length check if empty input should fail

