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
The Maybe type encapsulates an optional value. A value of type Maybe a either contains a value of type a (represented as Just a), or it is empty (represented as Nothing). Using Maybe is a good way to deal with errors or exceptional cases without resorting to drastic measures such as error.
It's merely an infix synonym for fmap , so you can write e.g. Prelude> (*2) <$> [1.. 3] [2,4,6] Prelude> show <$> Just 11 Just "11" Like most infix functions, it is not built-in syntax, just a function definition. But functors are such a fundamental tool that <$> is found pretty much everywhere.
Another simple example of a functor is the Maybe type. This object can contain a value of a particular type as Just , or it is Nothing (like a null value).
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.
You want sequence
from Control.Monad
.
(This is also generalized in a useful way in Data.Traversable
.)
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