我目前正在使用 haskell 开发板评估器。我正在尝试将 map 与具有多个参数的函数一起使用;我读过其他关于此问题的问题,但不断收到类型错误,所以也许我只是误解了 Haskell 类型(我是一名 Python 程序员)。不管怎样,代码如下:
scorePiecesRow [] _ = 0
scorePiecesRow (x:xs) y
| x == y = 1 + (scorePiecesRow xs y)
| x == '-' = 0 + (scorePiecesRow xs y)
| otherwise = -1 + (scorePiecesRow xs y)
scorePieces [] _ = 0
scorePieces board y = foldr (+) 0 (map (scorePiecesRow y) board)
当我传递诸如 "wwwb--"'w'
(返回 3
)之类的内容时, scorePiecesRow
工作得很好,但作为一旦我调用 scorePieces
(例如 scorePieces ["www", "bb-"] 'w'
应该返回 1
),我得到一堆类型错误:
<interactive>:37:14: Couldn't match expected type `Char' with actual type `[Char]' In the expression: "www" In the first argument of `scorePieces', namely `["www", "bb-"]' In the expression: scorePieces ["www", "bb-"] 'w' <interactive>:37:21: Couldn't match expected type `Char' with actual type `[Char]' In the expression: "bb-" In the first argument of `scorePieces', namely `["www", "bb-"]' In the expression: scorePieces ["www", "bb-"] 'w' <interactive>:37:28: Couldn't match expected type `[Char]' with actual type `Char' In the second argument of `scorePieces', namely 'w' In the expression: scorePieces ["www", "bb-"] 'w' In an equation for `it': it = scorePieces ["www", "bb-"] 'w'
我对错误消息有点困惑。例如,第一个告诉我,它需要 Char
,但 scorePiecesRow
的第一个参数采用 [Char]
。
如果有人能对此有所启发,我们将不胜感激!
最佳答案
虽然 Haskell 会为你推断类型,但它们通常对于记录你的代码(以机器检查的方式!)和检查你的假设也非常有值(value)。我们可以在这里使用 Haskell 的类型推断引擎来了解我们对这些函数的了解。
由于 scorePiecesRow
被添加到 1 + (scorePiecesRow xs y)
中的数字,我们知道结果必须位于类型类 Num
中(其中定义了 (+)
)
scorePiecesRow :: Num a => ... -> a
此外,通过查看参数中的模式匹配,我们可以很容易地看出第一个参数必须是一个列表。
scorePiecesRow :: Num a => [b] -> ... -> a
由于我们使用 (==)
比较第一个参数和第二个参数的元素,我们知道它们必须是相同的类型并且在类型类 Eq
中(其中定义了 (==)
!)。
scorePiecesRow :: (Num a, Eq b) => [b] -> b -> a
最后,第一个参数的元素与 '-'
进行比较,因此我们知道它们实际上必须是 Char
。由于 String
是 [Char]
的同义词,我们可以对此进行估算。
scorePiecesRow :: (Num a) => String -> Char -> a
我们可以对 scorePieces
进行同样的操作来了解这一点
scorePieces :: Num a => String -> String -> a
这就是我们看到问题的地方。您正在调用 scorePieces ["www", "bb-"] 'w'
,即使用 [String]
和 Char
,同时scorePieces
需要一个 String
和另一个 String
。
错误正是告诉您这一点,但这有点令人困惑,因为 String
和 [Char]
是相同的,并且 GHC 倾向于将类型简化为最简单的形式报告错误。
关于具有多个参数和类型问题的 Haskell 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19850089/