Filter over [Maybe a] and discard Nothing values

494 Views Asked by At

With a list of Maybe a, how to filter and take only the elements of the list which are not Nothing?

-- input
pas = [Just 3, Just 1, Just 5, Just 9, Nothing, Just 10, Nothing] :: [Maybe Int]

-- expected output
new_pas = [3, 1, 5, 9, 10]

I've tried different ways of using map and looked at mapMaybe but can't find the right combination.

3

There are 3 best solutions below

0
On BEST ANSWER

As well as the simple list comprehension you found, there is already a library function for this: catMaybes

And note that you can search Hoogle not only for names, but for type signatures - something which is really useful in many situations. Here entering [Maybe a] -> [a] gives you catMaybes straight away. (Confession: I'd forgotten the name of the function, but knowing it existed, found it exactly that way just now!)

0
On

While typing the question I've found the answer and it's actually straightforward:

new_pas = [pa | Just pa <- pas]
-- [3, 1, 5, 9, 10]

Putting it here for other people Googling the same question.

0
On

Your way with pattern-matching in list comprehension is quite nice. Yet, I also like the way Data.Maybe.mapMaybe you mentioned (note that it is just one line under Data.Maybe.catMaybe spoken of in this answer by Robin Zigmond) could be used here:

unwrapJusts :: [Maybe a] -> [a]
unwrapJusts = mapMaybe id

Your example:

GHCi> unwrapJusts [Just 3, Just 1, Just 5, Just 9, Nothing, Just 10, Nothing]
[3,1,5,9,10]

The idea is fairly simple: when traversing through the list mapMaybe id throws all the Nothings (which are id Nothings) away and turns Just xs into xs.