使用 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
。函数foldr
取a -> b -> b
类型的函数f
和b
类型的起始元素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
我有两个功能。如果列表的所有元素都为零,则第一个给出 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
。函数foldr
取a -> b -> b
类型的函数f
和b
类型的起始元素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