Classes

Operator Overloading

Classes are a mechanism used to allow the same function or operator to be used on objects of different type.

In this trivial example, we implement our own version of the equals class, and call it 'equ'.

file: mc.hs
1 -- here's the class we are defining
2 class Foo a where
3     equ :: a -> a -> Bool
4 
5 -- here are two data types who are members
6 -- of the class
7 data Bar = Barc Integer
8 data Baz = Bazc Double
9 
10 -- helper methods
11 ubarc (Barc a) = a
12 ubazc (Bazc a) = a
13 
14 -- make Bar an instance of Foo
15 instance Foo Bar where
16     equ a b = (ubarc a) == (ubarc b)
17 
18 -- make Baz an instance of Foo
19 instance Foo Baz where
20     equ a b = (ubazc a) == (ubazc b)
21 
22 -- create some data
23 t1 = Barc 3
24 t2 = Barc 4
25 t3 = Bazc 1.0
26 t4 = Bazc 1.0
27 
28 main = do
29     putStrLn(show(t1 `equ` t2))
30     putStrLn(show(t3 `equ` t4))
> ghc --make mc.hs; ./mc
[1 of 1] Compiling Main             ( mc.hs, mc.o )
Linking mc ...
False
True

Using the Built-In Eq Class

Here we define a type called Foo and make it an instance of equ.

file: mc2.hs
1 data Foo = Bar Int
2 
3 instance Eq Foo where
4     (==) (Bar a) (Bar b) = (a == b)
5 
6 main = putStrLn(show((Bar 3) == (Bar 4)))
> ghc --make mc2.hs; ./mc2
[1 of 1] Compiling Main             ( mc2.hs, mc2.o )
Linking mc2 ...
False

Fortunately, there is a far easier way of doing this that does what we want 99% of the time:

file: mc3.hs
1 data Foo = Bar Int
2     deriving Eq
3 
4 main = putStrLn(show((Bar 3) == (Bar 4)))
> ghc --make mc3.hs; ./mc3
[1 of 1] Compiling Main             ( mc3.hs, mc3.o )
Linking mc3 ...
False