如何解决这个Haskell类型错误?预期和实际类型不匹配
我正在尝试使用 foldr 和辅助函数将列表中的所有最大整数提取到另一个列表。我对 foldr 的理解与错误消息相冲突。这是我的代码:
largest :: [Int] -> [Int]
largest [] = []
largest xs = foldr largestHelper [] xs
largestHelper :: [Int] -> Int -> [Int]
largestHelper [] prev = [prev]
largestHelper (lrg : lrgs) prev | lrg < prev = [prev]
| lrg == prev = prev : (lrg : lrgs)
| otherwise = (lrg : lrgs)
在我看来,要评估的第一个函数是largestHelper整数列表的最后一个元素,而[]. 接下来是largestHelper使用列表的倒数第二个元素和前一个迭代,它只是最后一个元素,因为它是迄今为止最大的。等等。所以最后largest xs已经评估为一个列表,其中包含一个或多个整数,其中从给定列表中找到最大值。
以下是错误:
largest.hs:3:20: error:
* Couldn't match type `[Int]' with `Int'
Expected type: [Int] -> [Int] -> [Int]
Actual type: [Int] -> Int -> [Int]
* In the first argument of `foldr', namely `largestHelper'
In the expression: foldr largestHelper [] xs
In an equation for `largest':
largest xs = foldr largestHelper [] xs
|
3 | largest xs = foldr largestHelper [] xs
| ^^^^^^^^^^^^^
largest.hs:3:37: error:
* Couldn't match type `Int' with `[Int]'
Expected type: [[Int]]
Actual type: [Int]
* In the third argument of `foldr', namely `xs'
In the expression: foldr largestHelper [] xs
In an equation for `largest':
largest xs = foldr largestHelper [] xs
|
3 | largest xs = foldr largestHelper [] xs
|
第一个似乎是说largestHelper实际上正在接收两个整数列表,而不是它正在构造的列表。但是没有foldr将列表的元素largest一个一个地给出,因此 for 的第二个参数largestHelper确实是一个整数而不是一个整数列表?第二个似乎是说 for 的论点largest实际上是[[Int]]而不是[Int]。我不明白。
我非常感谢对这种混淆的澄清。我还不知道这是否有效,因为它不能编译,而且作为函数式编程和 Haskell 的初学者,我也很感激考虑到代码的逻辑和风格的评论。
回答
您的两种类型错误遵循模式Couldn't match type `foo' with `bar'和Couldn't match type `bar' with `foo'。问题是你的参数顺序错误largestHelper。foldr首先使用元素然后使用累加器调用它的函数,但是largestHelper首先需要累加器然后使用元素。切换它们的顺序,您的类型错误将得到修复。