Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function 使用map和foldr、haskell实现函数_Function_Haskell_Boolean_Fold - Fatal编程技术网

Function 使用map和foldr、haskell实现函数

Function 使用map和foldr、haskell实现函数,function,haskell,boolean,fold,Function,Haskell,Boolean,Fold,我有两个功能。如果列表中的所有元素都为零,则第一个为true allZero :: [Int] -> Bool allZero [] = False allZero [0] = True allZero (x:xs) | x == 0 && allZero xs = True |otherwise = False 如果列表中至少有一个元素为零,则第二个函数为true oneZero :: [Int] -> Bool oneZero [] = False on

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

allZero :: [Int] -> Bool
allZero [] = False
allZero [0] = True
allZero (x:xs)
  | x == 0 && allZero xs = True
  |otherwise = False
如果列表中至少有一个元素为零,则第二个函数为true

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
为True,有非零元素形式的证据来证伪假设。列表中没有元素,也没有与假设相矛盾的证据。)


我把它作为一个练习,使其适应计算
oneZero

foldr
函数的工作原理如下:

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

因此,您可以定义函数,以便:

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

您尝试了什么?你能用
foldr
实现
any
all
吗?@WillemVanOnsem我不太明白foldr是如何工作的。我知道map是如何工作的,但我不知道如何应用它。
allZero[]=False
令人惊讶。您确定不希望像您的非正式规范所暗示的那样,在这种情况下使用
True
?chi的上述评论所暗示的是,allZero可以被视为非onzero,并且在[]中肯定没有零,因此它应该返回True。这是通常要做的事。
allZero(x:xs)=x==0&&allZero-xs
oneZero(x:xs)=x==0 | | oneZero-xs
<代码>全部零=全部。映射(=0)
<代码>一个零=任何。映射(=0)
all==foldr(&&)True
any==foldr(| |)False
。(这不是一个完整的答案,因为里面没有任何文字,因此只留下评论。)我不确定我会称之为“惯例”。这是我们希望我们的逻辑具有的一些明显有用的属性的必要结论:。重新“约定”,它是
allZeroes(a++b)=allZeroes a和&allZeroes b
的结果,因此
allZeroes a=allZeroes(a++[])=allZeroes a和&allZeroes[]
,而
True
&
的标识元素。(另外,如果已经计算过,就没有短路。:)我认为
全零
是一个同态,因为
全零
被定义为
,而不是相反,但是的,“约定”不是最好的表达方式。
:t foldr(\x->x==0&)真
给出了一个错误。:)