提问人:jvkloc 提问时间:7/5/2021 更新时间:7/6/2021 访问量:204
如何解决这个Haskell类型错误?预期类型和实际类型不匹配
How to solve this Haskell type error? Expected and actual types do not match
问:
我正在尝试使用 foldr 和 helper 函数将所有最大的整数从一个列表提取到另一个列表。我对折叠器的理解与错误消息相冲突。这是我的代码:
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
largestHelper
largest
[[Int]]
[Int]
我将非常希望澄清这种混淆。我还不知道这是否可行,因为它不会编译,并且作为函数式编程和 Haskell 的初学者,考虑到代码的逻辑和风格,我也希望发表评论。
答:
您的两个类型错误遵循模式和 。问题是你对 的参数顺序错误。 调用其函数时,首先使用元素,然后使用累加器,但希望先使用累加器,然后使用元素。切换它们的顺序,您的类型错误将得到修复。Couldn't match type `foo' with `bar'
Couldn't match type `bar' with `foo'
largestHelper
foldr
largestHelper
让我们分解第一个错误消息:
largest.hs:3:20: error: [...] | 3 | largest xs = foldr largestHelper [] xs | ^^^^^^^^^^^^^
编译器在第 3 行第 20 列的文件中发现问题。它还打印了相关行。largest.hs
* In the first argument of `foldr', namely `largestHelper' In the expression: foldr largestHelper [] xs In an equation for `largest': largest xs = foldr largestHelper [] xs
再次给出位置,但这次是根据参数、表达式和方程式。我们了解到 .largestHelper
* Couldn't match type `[Int]' with `Int' Expected type: [Int] -> [Int] -> [Int] Actual type: [Int] -> Int -> [Int]
编译器应为 的类型为 ,但发现它的实际类型是 。由于它们在编译器上不同,因此报告了错误。largestHelper
[Int] -> [Int] -> [Int]
[Int] -> Int -> [Int]
[Int]
Int
因此,在查看错误消息后,我们最终得到了两个新问题:
- 为什么编译器期望是类型?这是关于统一的问题,在如何手动推断表达式的类型中有一些很好的答案。
largestHelpler
[Int] -> [Int] -> [Int]
- 如何解决该问题?约瑟夫-西布尔-恢复-莫妮卡的回答已经解释了这一点。
请注意,编译器之所以能够识别问题,是因为您的编程语言使用类型。也就是说,类型赋予了它发现代码有问题的能力。因此,编译器可能认为自己是你的好伙伴,而实际上它面对的是你最奇怪和最复杂的技术术语。由您来解决问题。
评论