Search code examples
haskelltypeclass

Error when making an instance of Eq typeclass in Haskell


I am learning Haskell and writing a small decision diagrams library as a starting project. I have declared the data type as

data DD a = DDNode { var :: Int, vals :: [DD a]} | DDLeaf { val :: a} deriving (Show, Eq)

For testing for equality between 2 DDs, I am making an instance of Eq for DD. It basically does the same as testing for node and leaf equality in the case of tree structures.

instance (Eq a) => DD a where
    (DDNode i vs) == (DDNode i' vs') = i == i' && vs == vs'
    (DDLeaf v) == (DDLeaf v') = v == v'
    _ ==  _ = False

When I load a file with the above code in GHCi, I get the following error,

Prelude> :load decisionDiagrams.hs
[1 of 1] Compiling DecisionDiagram  ( decisionDiagrams.hs, interpreted )

decisionDiagrams.hs:9:19: error:
    ‘==’ is not a (visible) method of class ‘DD’
Failed, modules loaded: none.

What am I doing wrong?


Solution

  • You can not use Eq both in deriving and in an instance declaration, since then there are two implementations. The deriving (Eq) should thus be removed:

    data DD a
      = DDNode { var :: Int, vals :: [DD a]}
      | DDLeaf { val :: a}
      deriving (Show)

    You need to specify that you are defining an instance of Eq, so the instance declaration should look like:

    --                 ↓ defining an instance for Eq
    instance (Eq a) => Eq (DD a) where
        -- …

    The Eq instance you are implementing, is the one that Haskell can automatically derive. You thus do not need to construct such instance yourself: you can do this with a deriving clause. There is thus no reason to implement Eq manually.