使用 map 和 foldr 实现功能,haskell

Implement the functions using map and foldr, haskell

我有两个功能。如果列表的所有元素都为零,则第一个给出 true

allZero :: [Int] -> Bool
allZero [] = False
allZero [0] = True
allZero (x:xs)
  | x == 0 && allZero xs = True
  |otherwise = False

如果列表中至少有一个元素为零,则第二个函数返回真

oneZero :: [Int] -> Bool
oneZero [] = False
oneZero (x:xs)
   | x == 0 = True
   | otherwise = oneZero xs

也许还有另一种方法可以解决这个问题。例如使用 map 或 foldr? 谢谢

foldr基本上以你的守卫为折叠功能:

allZero = foldr (\x acc -> x == 0 && acc) True

acc(对于accumulator)是递归调用的已计算值。作为右关联,列表中的第一个非零值会使列表其余部分的折叠函数的计算短路。

(请注意,按照惯例 allZero [] == True。“假设”是 allZero xs 为真,以非零元素的形式证明假设是错误的。没有元素在列表,没有证据反驳假设。)

我把它留作练习,以适应它来计算 oneZero

foldr 函数是这样工作的:

假设,您有列表 [1, 2, 3]。让我们把这个列表写成 (:) 1 ((:) 2 ((:) 3 [])),其中每个元素的类型都是 a。函数foldra -> b -> b类型的函数fb类型的起始元素z,只需将[]替换为z :f。所以,foldr f z ((:) 1 ((:) 2 ((:) 3 []))) == f 1 (f 2 (f 3 z)).

因此,您可以这样定义函数:

allZero = foldr (\x -> x == 0 &&) True

oneZero = foldr (\x -> x == 0 ||) False