Is it possible to use all
on a [Maybe Int]
list?
I know all (< 9) [2,4,6,8,10]
returns False
, but that is using a list with just integers.
I am trying to accomplish something similar except with a list that looks like this:[Just 3, Just 6, Nothing, Nothing, Just 7]
I want all (<=9) [Just 3, Just 6, Nothing, Nothing, Just 7]
to return True
> all (<= Just 9) [Just 3, Just 6, Nothing, Nothing, Just 7]
True
This works because Nothing
is less than any Just x
.
Alternatively, one can use catMaybes :: [Maybe a] -> [a]
from the Data.Maybe
module to discard the Nothing
s, and remove the Just
wrappers, turning the list into a list of numbers, which can then be handled as usual:
> all (<= 9) $ catMaybes [Just 3, Just 6, Nothing, Nothing, Just 7]
True
Another alternative: define your own predicate on Maybe Int
.
let p :: Maybe Int -> Bool
p Nothing = True
p (Just x) = x <= 9
in all p [Just 3, Just 6, Nothing, Nothing, Just 7]
Even better: define p
using maybe
, as Zeta suggests.
Yet another alternative, using a list comprehension and and
:
and [ x <= 9 | Just x <- [Just 3, Just 6, Nothing, Nothing, Just 7] ]
Sure. maybe True (< 9)
. maybe default func
uses the given function func
if you have Just
, or the default
if you have Nothing
:
ghci> all (maybe True (< 9)) [Just 3, Just 6, Nothing, Nothing, Just 7]
True
You can use that to write your allMaybe
function:
allMaybe :: (a -> Bool) -> [Maybe a] -> Bool
allMaybe p = all (maybe True p)
Or we could "lift" your predicate to Maybe
:
liftP :: (a -> Bool) -> Maybe a -> Bool
liftP _ Nothing = True
liftP p (Just x) = p x
-- or simply
-- liftP p = maybe True p
allMaybe' p = all (liftP p)
But that only hides the underlying maybe
away.
A slightly more esoteric solution than those by chi and Zeta would be using Compose
so that all
sees the two layers as a single structure containing numbers:
GHCi> import Data.Functor.Compose
GHCi> all (<=9) $ Compose [Just 3, Just 6, Nothing, Nothing, Just 7]
True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With