![](/img/trans.png)
[英]Haskell: No instance for (Eq a) arising from a use of `==' In the expression: (b == c)
[英]Haskell no instance for (Eq Digit) arising from a use of == In the expression: x == One
data Digit = Zero | One
convBNum :: [Digit] -> Int
convBNum [] = 0
convBNum (x:xs)
| x == One = 2^length xs + convBNum xs
| otherwise = convBNum xs
這是一個簡單函數的代碼,該函數將二進制數轉換為int。 當我編譯它時,它給了我這個錯誤:
no instance for (Eq Digit) arising from a use of ==
In the expression: x == One
如果我很好理解,還閱讀其他問題,那么問題是x不能是任何類型,但是我不明白如何解決此問題以及如何使用Eq約束。
添加deriving
子句
data Digit = Zero | One deriving (Eq)
或不使用==
,而使用模式匹配:
convBNum (One:xs) = 2^length xs + convBNum xs
convBNum (_ :xs) = convBNum xs
問題是x不能是任何類型
在您的代碼中x
類型為Digit
而這正是它應該具有的類型。 那不是問題。
問題是==
運算符在Eq
類型類中定義。 這意味着它只能用於屬於該類型類實例的類型,而您的Digit
類型則不能。 為了使它成為一體,您可以為Digit
提供自己的==
定義,如下所示:
instance Eq Digit where
Zero == Zero = True
One == One = True
_ == _ = False
但是,可以使用deriving
關鍵字為自定義數據類型自動定義某些類型類(例如Eq
, Ord
, Show
和Read
)的定義,這通常是更可取的。 所以你可以這樣寫:
data Digit = Zero | One deriving Eq
這將自動生成上述Eq
實例。
請注意,對於您的用例,使用嵌套模式匹配比使用==
更慣用:
convBNum :: [Digit] -> Int
convBNum [] = 0
convBNum (One : xs) = 2^length xs + convBNum xs
convBNum (Zero : xs) = convBNum xs
這樣,您甚至都不需要Eq
實例,但是無論如何都要使用它,因為Digit
是確實應該支持==
的類型。
無關緊要的是,您可能還應該為Show
派生或手動定義實例,以便可以print
數字並將其顯示在GHCi中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.