i am looking for a function which takes a function (a -> a -> a) and a list of [Maybe a] and returns Maybe a. Hoogle gave me nothing useful. This looks like a pretty common pattern, so i am asking if there is a best practice for this case?
>>> f (+) [Just 3, Just 3]
Just 6
>>> f (+) [Just 3, Just 3, Nothing]
Nothing
Thanks in advance, Chris
You should first turn the
[Maybe a]into aMaybe [a]with all theJustelements (yieldingNothingif any of them areNothing).This can be done using sequence, using Maybe’s Monad instance:
The definition of sequence is equivalent to the following:
So we can expand the latter example as:
Using the do-notation expression of the monad laws, we can rewrite this as follows:
If you know how the Maybe monad works, you should now understand how
sequenceworks to achieve the desired behaviour. 🙂You can then compose this with
foldrusing(<$>)(from Control.Applicative; equivalently,fmaporliftM) to fold your binary function over the list:Of course, you can use any fold you want, such as
foldr,foldl1etc.As an extra, if you want the result to be
Nothingwhen the list is empty, and thus be able to omit the zero value of the fold without worrying about errors on empty lists, then you can use this fold function:and similarly for
foldr,foldl, etc. You’ll need to import Control.Monad for this.However, this has to be used slightly differently:
or
This is because, unlike the other folds, the result type looks like
m ainstead ofa; it’s a bind rather than a map.