[英]Haskell: Could not deduce (Eq a) arising from the literal ‘1’ from the context (Num a)
[英]Could not deduce (Eq a) from the context (…)
我是 Haskell 的新手。 我寫了這段代碼:
deleteDuplicates :: [a] -> [a]
deleteDuplicates [] = []
deleteDuplicates (x:xs)
| x == (head xs) = x : (deleteDuplicates (tail xs))
| otherwise = x : (head xs) : (deleteDuplicates (tail xs))
這個錯誤是什么意思,為什么會發生? 我是否不小心以某種方式比較了兩種不同的類型?
set2.hs:10:3:
Could not deduce (Eq a) from the context ()
arising from a use of `==' at set2.hs:10:3-16
Possible fix:
add (Eq a) to the context of
the type signature for `deleteDuplicates'
In the expression: x == (head xs)
In a stmt of a pattern guard for
the definition of `deleteDuplicates':
x == (head xs)
In the definition of `deleteDuplicates':
deleteDuplicates (x : xs)
| x == (head xs) = x : (deleteDuplicates (tail xs))
| otherwise = x : (head xs) : (deleteDuplicates (tail xs))
您的類型簽名錯誤:
deleteDuplicates :: [a] -> [a]
這表示您的 function 可以處理任何類型的列表a
,但事實並非如此:您稍后致電:
x == (head xs)
因此,您必須能夠比較您的類型是否相等。 意味着簽名必須是:
deleteDuplicates :: Eq a => [a] -> [a]
在這種情況下,最好刪除顯式類型簽名,在 GHCi 中加載 function 並發現解釋器認為它應該具有的類型(通過:t deleteDuplicates
)。
更多錯誤
此外,您對head
的使用是一個壞主意。 head
是部分 function 並且在xs == []
時會失敗。 我建議你擴展模式匹配:
deleteDuplicates (x1:x2:xs)
| x1 == x2 = ...
| otherwise = x1 : deleteDuplicates (x2:xs)
另請注意對otherwise
情況的修復。 您正在跳過 x2,但是如果 x2 匹配列表中的下一個元素怎么辦? 像[1,2,2,3]
這樣的東西會發現1 /= 2
然后遞歸會得到列表[2,3]
- 哎呀!
編譯器告訴您,僅從類型簽名就無法確定a
是否為 instanceof Eq
。
deleteDuplicates :: Eq a => [a] -> [a]
您需要通過在簽名中提及它來告訴編譯器a
是Eq類型 class 的實例。
表達方式
x == (head xs)
需要在xs
的成員上定義==
,這意味着a
必須是類型類Eq
的實例。 將函數的類型簽名更改為
deleteDuplicates :: Eq a => [a] -> [a]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.