# Can I use == and /= without using Eq?

• A+
Category：Languages

So I wrote this program and everything works fine I would like to improve it. I would also be able to compile two different time sets with the use of /= and get True as an result. I am a little bit confused.

``data Time = Localtime {hour, minute :: Int}               | Globaltime {hour, minute, difference :: Int}               | LocaltimeAM {hour, minute :: Int, am :: Bool}               deriving Show  same :: Time -> Time -> Bool same u1 u2 = (h u1) == (h u2)    where       h :: Time -> (Int, Int) -- (Int, Int) = (hour, minute)       h (Localtime h m) = (h, m)       h (Globaltime h m d) = ((h+d+24) `mod` 24, m)        h (LocaltimeAM h m am) = (h + (if am then 0 else 12), m) ``

To answer the question in the title:

Can I use `==` and `/=` without using `Eq`?

You could - technically speaking - explicitly hide the `Eq` typeclass in the prelude, and then define a `(==)` and `(/=)` function yourself, but that would be a bad idea, since it would mean that you can no longer compare two integers with `(==)`.

What you probably want is to make `Time` an instance of the `Eq` typeclass, such that you can from now on write `time1 == time2`. We can make it an instance like:

``h :: Time -> (Int, Int) -- (Int, Int) = (hour, minute) h (Localtime h m) = (h, m) h (Globaltime h m d) = ((h+d+24) `mod` 24, m)  h (LocaltimeAM h m am) = (h + (if am then 0 else 12), m)  instance Eq Time where     t1 == t2 = (h t1) == (h t2)``

Haskell will automatically write the `(/=)` function for us (as the opposite of `(==)`), or you can decide to write the `(/=)` version, and then Haskell will write the `(==)` version. Of course you can also implement both.

Making types a member of a typeclass actually can be useful. Take for example the `nub :: Eq a => [a] -> [a]` function. It requires that the type `a` is a member of the `Eq` typeclass, and performs some sort of "uniqness" filter: you provide it a list of elements, and it returns a list of non-equal elements. Now without any work to define a `nub` function for your `Time` type, by making `Time` an instance of the `Eq` type class, you can use `nub` on a list of `Time`s.

Of course you can not simply make a type an instance of all possible type classes. You should only make types an instance of the `Eq` typeclass if you can check if two items are the same (and there should thus be a "reasonable" idea when two items are equal). Furthermore most of these typeclasses come with "contracts": for example an equality relation (like defined by `(==)`) should be reflexive, symmetric, and transitive.