Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flattening a list of Maybe elements from Just [[x1],[x2]] to Just [x1,x2]

Tags:

haskell

monads

I have a function I'm supposed to define like so:

func :: (a -> Maybe [b]) -> [a] -> Maybe [b]

Some examples of how it's supposed to work :

func (\x -> if x == 0 then Nothing else Just [x]) [1,2]

Should result in:

Just [1,2]

Another example:

func (\x -> if x == 0 then Nothing else Just [x]) [1,0]

Nothing

If anything in the list is a Nothing, then the function returns Nothing. Otherwise if all the elements in the list return a Just [x] then it's supposed to return a list like: Just [x1, x2, ...].

I tried using fmap for similar calls to the above which returns something like:

[Just [1], Just [2], ...]

If I use sequence on the list fmap returns, it'll follow the rules of the above (returning a Nothing if anything in the list is a Nothing), which is great. Except it returns a list like this:

Just [[1],[2]]

which is not the format I need. In that case I would need it to be:

Just [1,2]

As I just started learning Haskell and monads are still a fresh topic to me, I'm having some trouble figuring how to format this list or if there's a better way of solving this problem. I cannot change the function type signature.

like image 652
weztex Avatar asked Jan 02 '23 01:01

weztex


1 Answers

To turn a list like [[1],[2]], into [1,2], use concat. In your case, since the list is inside a Maybe, you'll need to call fmap concat on it.

Also, note that any time you call sequence (or sequenceA) on the result of map, fmap, or <$>, you can save a function by combining both into mapM (or traverse).

like image 133
Joseph Sible-Reinstate Monica Avatar answered May 23 '23 07:05

Joseph Sible-Reinstate Monica