mapMaybe function resides in the
Data.Maybe of the
base library, but it is not available in the
Prelude module. It is a useful filtering function.
λ> import Data.Maybe λ> :type mapMaybe mapMaybe :: (a -> Maybe b) -> [a] -> [b]
It takes an
(a -> Maybe b) function and maps that over a list of
a values. The return values is a list of
Nothing values from the application of the
(a -> Maybe b) function will be filtered out, and the
Just constructors will also be removed from the final list. The documentation gives a good example, altered a bit here to use type applications:
λ> :set -XTypeApplications λ> import Text.Read ( readMaybe ) λ> :type readMaybe readMaybe :: Read a => String -> Maybe a λ> mapMaybe (readMaybe @Int) ["1", "2", "Julie", "3", ""] [1,2,3]
@Int is a type application that tells
readMaybe what the return type should be; the “read” functions usually need to be told what type of value they are trying to “read” out of the strings they’re applied to. Notice how it nicely filters out the values that cannot be read as
While the basic
mapMaybe is specialized to lists, there are plenty of other versions of it around, specialized to other types of collections.
And there is another we’d like to highlight, a less specialized version in the
mapMaybe :: Filterable f => -> Maybe b) -> f a -> f b (a
In this package,
mapMaybe is one of the two primary methods of the typeclass called
Filterable, which is described as being like
Functor, but with
Maybe effects. In turn,
Filterable allows us to have a special kind of “traversable” typeclass called
Witherable that allows for traversal of data structures while pruning – or “withering” – them by removing some elements (the
Nothings). You’ll find instances here for some of the same types we just listed as having specializations of
Map, etc.) but here they’re gathered into one typeclass.
λ> :m Data.Char Data.Witherable Data.Map λ> isWord xs = if (all isAlpha xs) then (Just xs) else Nothing isWord :: Foldable t => t Char -> Maybe (t Char) λ> Data.Witherable.mapMaybe isWord (fromList [(5,"a"), (3," ")]) fromList [(5,"a")] λ> Data.Map.mapMaybe isWord (fromList [(5,"a"), (3," ")]) fromList [(5,"a")]
Note that the
Data.Map are the same for the
And a few, such as an instance for
Either, are available that don’t exist elsewhere.
λ> fmap isWord (Right "123") Right Nothing λ> Data.Witherable.mapMaybe isWord (Right "123") Left ()