我有两个函数计算整数列表的长度

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/

10-16 06:52