Question

I would like to have a function with the type:

f :: [Maybe a] -> Maybe [a]

e.g.

f [Just 3, Just 5] == Just [3, 5]
f [Just 3, Nothing] == Nothing
f [] == Just []

It is similar to catMaybes :: [Maybe a] -> [a] in Data.Maybe, except that catMaybes ignores Nothing, while my f is very serious about Nothing. I could implement f in a naive way (as shown below), but wondering if there is more idiomatic way (like "applicative functor"):

f :: [Maybe a] -> Maybe [a]
f xs = let ys = catMaybes xs
        in if length ys == length xs 
           then Just ys
           else Nothing

or

f :: [Maybe a] -> Maybe [a]
f xs = if all isJust xs
        then catMaybes xs
        else Nothing
Was it helpful?

Solution

The function you're searching for is called sequence:

sequence :: (Monad m) => [m a] -> m [a]

You can find this function using hoogle: link.

Example:

>>> sequence [Just 3, Just 5]
Just [3,5]

>>> sequence [] :: Maybe [Int]
Just []

Note: There is also sequenceA in Data.Traversable which is a bit generalized, but for your use case sequence from Control.Monad is enough.

OTHER TIPS

You want sequence from Control.Monad.

(This is also generalized in a useful way in Data.Traversable.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top