给定布尔列表的列表,返回一个布尔

时间:2019-06-09 19:21:58

标签: haskell

我有一个函数,定义如下,该函数被赋予布尔列表的列表并返回一个布尔:

evaluates :: [[Bool]] -> Bool

我尝试了以下方法:

evaluates  :: [[Bool]] -> Bool
evaluates  ((y:ys):xs) = (y && (head ys)) || evaluates (tail xs)

但这不起作用。

我期望的结果是:

[True && False && True] ||  [True] || [False && False]] = True

对于以下项的输入:[[True, False, True], [True], [False, False]]

1 个答案:

答案 0 :(得分:11)

您尝试在单个函数中执行太多操作。让我们分三步解决问题:

  1. 创建一个包含Bool列表的函数,并返回这些Bool的逻辑与;
  2. 创建一个函数,该函数接受Bool的列表并返回这些Bool的逻辑或;和
  3. 创建一个包含[Bool]列表的函数,首先将其与第一个函数映射,然后在其上执行第二个函数。

我们可以使用foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b实现第一个功能:

_and :: [Bool] -> Bool
_and = foldr (&&) True

事实上,Haskell的前奏已经具有一个and :: Foldable f => f Bool -> Bool功能。

第二个功能也可以用foldr来实现:

_or :: [Bool] -> Bool
_or = foldr (||) False

Haskell的前奏已经具有一个or :: Foldable f => f Bool -> Bool功能。

现在我们可以用map :: (a -> b) -> [a] -> [b]来定义evaluate

evaluate :: [[Bool]] -> Bool
evaluate = _or . map _and

我们甚至可以将以上内容概括为两个(可能是不同的)Foldable

evaluate :: (Foldable f, Foldable g) => f (g Bool) -> Bool
evaluate = foldr ((||) . and) False

或者像@DanielWagner所说,我们可以使用any :: Foldable f => (a -> Bool) -> f a -> Bool

evaluate :: (Foldable f, Foldable g) => f (g Bool) -> Bool
evaluate = any and

例如:

Prelude> evaluate [[True, False, True], [True], [False, False]]
True
Prelude> evaluate [Just False, Just False, Nothing]
True
Prelude> evaluate [Just False, Just False, Just False]
False
Prelude> evaluate (Just [True, False, True])
False
Prelude> evaluate (Just [True, True, True])
True
相关问题