我有两个函数来计算整数列表的长度
lengthFoldl :: [Int] -> Int
lengthFoldl xs = (foldl (\_ y -> y+1) 0 xs)
Run Code Online (Sandbox Code Playgroud)
和
lengthFold :: [a] -> Int
lengthFold xs = foldr (\_ y -> y+1) 0 xs
Run Code Online (Sandbox Code Playgroud)
它们是相同的,除了一个使用foldr和一个foldl.
但是当试图计算任何列表的长度时,[1 .. n]我从lengthFoldl得到了错误的结果(一个太大).
为了补充joelfischerr的答案,我想指出你的函数类型给出了一个提示.
lengthFoldl :: [Int] -> Int
lengthFold :: [a] -> Int
Run Code Online (Sandbox Code Playgroud)
他们为什么不同?我猜你可能不得不改变第一个,[Int]因为[a]它没有编译.然而这是一个很大的警示标志!
如果确实在计算长度,为什么要lengthFoldl关心列表元素的类型是什么?为什么我们需要元素为Ints?只需要一种可能的解释Int:查看代码
lengthFoldl xs = foldl (\_ y -> y+1) 0 xs
Run Code Online (Sandbox Code Playgroud)
我们可以看到这里唯一的数字变量是y.如果y被强制为数字,并且列表元素也被强制为数字,则好像y被视为列表元素!
事实确实如此:foldl首先将累加器传递给函数,将列表元素传递给第二个,不像foldr.
一般的拇指规则是:当类型和代码不一致时,应该仔细考虑哪一个是正确的.我会说大多数Haskellers会认为,在大多数情况下,比正确的代码更容易获得正确的类型.因此,不应该只是将类型调整为代码以强制它编译:类型错误可以反而见证代码中的错误.
| 归档时间: |
|
| 查看次数: |
501 次 |
| 最近记录: |