简体   繁体   中英

Creating Instance of Eq for custom data type in Haskell

I have made some custom Data types for number representation in Haskell, now I want to implement Eq instances for it, but I am somehow stuck. So I have already made:

data Digit = Zero | One | Two
type Digits = [Digit]
data Sign = Pos | Neg -- Pos fuer Positive, Neg fuer Negative
newtype Numeral = Num (Sign,Digits)

instance Eq Sign where
(==) Pos Pos = True
(==) Neg Neg = True
(==) _ _ = False

instance Eq Digit where
(==) Zero Zero = True
(==) One One = True
(==) Two Two = True
(==) _ _ = False

Now I want to check out the Sign in my custom type Numeral so I tried this:

instance (Eq Sign) => Eq (Numeral) where
(==) Num(x,_)== Num(y,_) = x==y

But I get this error: Parse error in pattern : (==)

Mostly putting what I've already written in the comments in a more fleshed out form:

There are a few problems with your code:

  1. You have to indent the code under the instance declarations. That way you tell the compiler what code belongs to the instance declaration.
  2. In the following line you are asking for a type class constraint on a concrete type ( Eq Sign => ). This is not possible in standard Haskell and even if you were to follow the compiler instructions and enable the FlexibleInstances language extension it wouldn't make sense.

     instance (Eq Sign) => Eq (Numeral) where 

    Type class constraints are only used for type variables. For example:

     double :: Num a => a -> a double x = x + x 

    Here we say, that the function double only works for all types that implement Num . double :: Num Int => Int -> Int on the other hand is redundant, because we already know, that Int has a Num instance. The same for Eq Sign .

    For instances such constraints only make sense, if the type you are writing an instance for contains another polymorphic type. Fox example instance Ord a => Ord [a] . Here we would use the Ord instance of the elements of the list to lexiographically order lists.

  3. You can define (==) either in infix or prefix form, but not both. So either (==) (Num (x,_)) (Num (y,_)) = x == y or Num (x,_) == Num (y,_) = x == y .

  4. Newtyping tuples to create a product type is rather strange. Newtypes are usually used if you want to use the functionality that is already present for the more complex underlying type. However here that is not the case, you just want a normal product of Digits and Sign .

  5. You are only comparing the Sign of the numbers. While technically a valid Eq instance, I think you also want to compare the digits of the number probably truncating leading zeros. In the code below I didn't truncate zeros though, to keep it simple.

data Digit = Zero | One | Two
type Digits = [Digit]
data Sign = Pos | Neg
data Numeral = Num Sign Digits

instance Eq Sign where
  (==) Pos Pos = True
  (==) Neg Neg = True
  (==) _ _ = False

instance Eq Digit where
  (==) Zero Zero = True
  (==) One One = True
  (==) Two Two = True
  (==) _ _ = False

instance Eq Numeral where
  Num s1 x1 == Num s2 x2 = s1 == s2 && x1 == x2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM