What's a good way to convert List (Maybe a)
to Maybe (List a)
in Elm?
The logic is simple:
Just (List a)
if all items are Just a
Nothing
.Example 1:
input: [ Just 1, Just 2, Just 3 ]
output: Just [ 1, 2, 3 ]
Example 2:
input: [ Just 1, Nothing, Just 3 ]
output: Nothing
Can it be done easily with some of the built-in functions?
The best I came up with looks like this:
listOfMaybesToMaybeList : List (Maybe a) -> Maybe (List a)
listOfMaybesToMaybeList listOfMaybes =
List.foldl
(\maybeItem ->
\maybeResultList ->
case ( maybeItem, maybeResultList ) of
( Just item, Just resultList ) ->
Just (List.append resultList [ item ])
( _, _ ) ->
Nothing
)
(Just [])
listOfMaybes
And what would be an appropriate name for this kind of function? As I was searching for an answer, I saw that there's a function called sequence
in Haskell which seems to be doing something similar.
@Chad Gilbert's answer sure is correct, but if you're looking for a simpler implementation of such a function, then the following line will do the trick:
listOfMaybesToMaybeList : List (Maybe a) -> Maybe (List a)
listOfMaybesToMaybeList listOfMaybes =
List.foldr (Maybe.map2 (::)) (Just []) listOfMaybes
Or just:
listOfMaybesToMaybeList : List (Maybe a) -> Maybe (List a)
listOfMaybesToMaybeList = List.foldr (Maybe.map2 (::)) (Just [])
Maybe.map2 just takes a function and two Maybe
values and applies the function to the values:
> Maybe.map2 (+) (Just 2) (Just 3)
Just 5 : Maybe.Maybe number
> Maybe.map2 (::) (Just 2) (Just [1])
Just [2,1] : Maybe.Maybe (List number)
Note, that (::)
function (prepend to the list) is used instead of (++)
or List.append
because it's more performant for the lists. Then foldr
must be used instead of foldl
to retain the order.
You can use the Elm Fancy Search tool and search on the function signature: List (Maybe a) -> Maybe (List a)
The first result turns up Maybe.Extra.combine
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With