我有两个函数计算整数列表的长度
lengthFoldl :: [Int] -> Int
lengthFoldl xs = (foldl (\_ y -> y+1) 0 xs)
和
lengthFold :: [a] -> Int
lengthFold xs = foldr (\_ y -> y+1) 0 xs
它们相同,除了一个使用文件夹和一个文件夹。
但是,当尝试计算任何列表
[1 .. n]
的长度时,我从lengthFoldl得到错误的结果(一个太大)。 最佳答案
为了补充joelfischerr的回答,我想指出,您的函数类型给出了提示。
lengthFoldl :: [Int] -> Int
lengthFold :: [a] -> Int
他们为什么不同?我猜您可能必须更改第一个以使用
[Int]
的方法,因为使用[a]
时它无法编译。但是,这是一个很大的警告信号!如果确实在计算长度,为什么
lengthFoldl
关心列表元素的类型是什么?为什么我们需要元素成为Int
?对于Int
,只有一种可能的解释:查看代码lengthFoldl xs = foldl (\_ y -> y+1) 0 xs
我们可以看到这里唯一的数字变量是
y
。如果y
被强制为数字,并且列表元素也被强制为数字,则似乎y
被视为列表元素!的确如此:
foldl
首先将累加器传递给函数,然后将列表元素传递给函数,这与foldr
不同。一般的经验法则是:当类型和代码不一致时,应仔细考虑哪一种是正确的。我想说大多数Haskellers会认为,在大多数情况下,正确的类型比正确的代码容易。因此,不应该只是将类型改编为代码以迫使其进行编译:类型错误可以代替见证代码中的错误。
关于haskell - 带有折叠架和折叠架的长度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50984485/