Reputation: 1684
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.
Upvotes: 10
Views: 1994
Reputation: 15045
@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.
Upvotes: 6
Reputation: 36385
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
Upvotes: 10