Может ли "все" применяться к списку "Может быть"?
Можно ли использовать all
в списке [Maybe Int]
?
Я знаю, что all (< 9) [2,4,6,8,10]
возвращает False
, но использует список с целыми числами.
Я пытаюсь выполнить что-то подобное, за исключением списка, который выглядит так:
[Just 3, Just 6, Nothing, Nothing, Just 7]
Я хочу all (<=9) [Just 3, Just 6, Nothing, Nothing, Just 7]
вернуть True
Ответы
Ответ 1
> all (<= Just 9) [Just 3, Just 6, Nothing, Nothing, Just 7]
True
Это работает, потому что Nothing
меньше любого Just x
.
В качестве альтернативы можно использовать catMaybes :: [Maybe a] -> [a]
из модуля Data.Maybe
для удаления Nothing
s и удалить обертки Just
, превратив список в список чисел, который затем можно обрабатывать, как обычно:
> all (<= 9) $ catMaybes [Just 3, Just 6, Nothing, Nothing, Just 7]
True
Другая альтернатива: укажите свой собственный предикат на 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]
Еще лучше: define p
с помощью maybe
, поскольку предлагает Zeta.
Еще одна альтернатива, использующая понимание списка и and
:
and [ x <= 9 | Just x <- [Just 3, Just 6, Nothing, Nothing, Just 7] ]
Ответ 2
Несколько более эзотерическое решение, чем chi и Zeta, будет использовать Compose
, так что all
видит два слоя как одну структуру, содержащую числа:
GHCi> import Data.Functor.Compose
GHCi> all (<=9) $ Compose [Just 3, Just 6, Nothing, Nothing, Just 7]
True
Ответ 3
Конечно. maybe True (< 9)
. maybe default func
использует заданную функцию func
, если у вас есть Just
или default
, если у вас есть Nothing
:
ghci> all (maybe True (< 9)) [Just 3, Just 6, Nothing, Nothing, Just 7]
True
Вы можете использовать это, чтобы написать свою функцию allMaybe
:
allMaybe :: (a -> Bool) -> [Maybe a] -> Bool
allMaybe p = all (maybe True p)
Или мы могли бы "поднять" ваш предикат до 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)
Но это скрывает только скрытый Maybe
.