Reputation: 159
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 : (==)
Upvotes: 7
Views: 12527
Reputation: 2366
Mostly putting what I've already written in the comments in a more fleshed out form:
There are a few problems with your code:
instance
declarations. That way you tell the compiler what code belongs to the instance declaration.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.
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
.
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
.
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
Upvotes: 6