簡體   English   中英

無法從上下文 (…) 中推斷出 (Eq 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]

您需要通過在簽名中提及它來告訴編譯器aEq類型 class 的實例。

表達方式

x == (head xs)

需要在xs的成員上定義== ,這意味着a必須是類型類Eq的實例。 將函數的類型簽名更改為

deleteDuplicates :: Eq a => [a] -> [a]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM