Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function in haskell that like catMaybes, but having type [Maybe a] -> Maybe [a]

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
like image 625
Causality Avatar asked Aug 02 '13 00:08

Causality


People also ask

Is maybe a type in Haskell?

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.

What does <$> mean in Haskell?

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.

Is maybe a functor Haskell?

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).


2 Answers

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.

like image 123
bennofs Avatar answered Oct 13 '22 00:10

bennofs


You want sequence from Control.Monad.

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

like image 44
shachaf Avatar answered Oct 12 '22 23:10

shachaf