簡體   English   中英

Haskell沒有因使用==而產生(Eq Digit)的實例在表達式中:x == One

[英]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關鍵字為自定義數據類型自動定義某些類型類(例如EqOrdShowRead )的定義,這通常是更可取的。 所以你可以這樣寫:

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.

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