# Typeclasses in Haskell

A typeclass is a sort of interface which defines a behaviour. They are kind of like interfaces in Java in the sense if a type is a part of a typeclass it must implement the behaviour the typeclass specifies.

For example, what is type signature of `==`

:

```
λ: :t (==)
(==) :: Eq a => a -> a -> Bool
```

The part between `::`

and `=>`

is the class constraint. Here it specifies that there is only one type supported for this operation parameters (`a`

) and that type must be part of the typeclass `Eq`

.

Similarly:

```
λ: :t (>=)
(>=) :: Ord a => a -> a -> Bool
```

Here, it is specifying that the input params must be of same type and they must implement the typeclass `Ord`

.

The `elem`

function has the type:

```
λ: :t elem
elem :: (Foldable t, Eq a) => a -> t a -> Bool
```

Here the type of the element and the element array individual element must be same and that type should implement `Eq`

.

For example this won’t work: `elem 'dog' [1, 2, 3]`

.

## Basic Typeclasses

### Eq

`Eq`

used for types that support equality testing. They implement: `==`

and `/=`

.

```
λ: 5 == 5
True
λ: 4 == 5
False
λ: 4 /= 5
True
λ: 4 /= 4
False
```

### Ord

`Ord`

used for types that support ordering. They implement `>`

, `>=`

, `<`

, and `<=`

.

The `compare`

function takes two `Ord`

values and returns an enum: `EQ`

, `LT`

, `GT`

.

```
λ: :t compare
compare :: Ord a => a -> a -> Ordering
λ: compare 2 2
EQ
λ: compare 2 1
GT
λ: compare 2 3
LT
λ: LT
LT
```

### Show and Read

`Show`

members can be presented as strings. It’s equivalent to the method `toString`

in Java and `__str__`

in python. They implement the `show`

method.

```
λ: show 3
"3"
λ: show "Cat"
"\"Cat\""
λ: show 'c'
"'c'"
λ: show True
"True"
```

`Read`

is sort of the opposite typeclass of Show. The read function takes a string and returns a type which is a member of Read. They implement the `read`

method.

```
λ: read "8" :: Int
8
λ: read "8.2" :: Float
8.2
λ: read "True" :: Bool
True
```

Please note `read`

method needs an inference type to figure out the type of the result. Without that it won’t be able to figure out to which type’s read method would be call. That is done by `::`

.

### Enum

`Enum`

members are sequentially ordered types with names. We can use them in ranges (as they are ordered). They implement the `succ`

and `pred`

methods.

```
λ: ['a'..'e']
"abcde"
λ: [LT .. GT]
[LT,EQ,GT]
λ: [3 .. 5]
[3,4,5]
λ: succ 'q'
'r'
λ: pred 43
42
```

### Bounded

`Bounded`

members have a upper and a lower bound. They implement the `minBound`

and `maxBound`

methods.

```
λ: minBound :: Int
-9223372036854775808
λ: minBound :: Char
'\NUL'
λ: minBound :: Bool
False
λ: maxBound :: Bool
True
λ: maxBound :: Char
'\1114111'
λ: maxBound :: Int
9223372036854775807
```

### Num

`Num`

is a numeric typeclass. Its members basically have to behave like well…a number.

Numeric literals practically act like polymorphic constants. They can act like any type that’s a member of the `Num`

typeclass.

```
λ: 20 :: Int
20
λ: 20 :: Integer
20
λ: 20 :: Float
20.0
λ: 20 :: Double
20.0
```

To join `Num`

the type must satisfy both `Show`

, and `Eq`

as well as a glut of other operations.

Examining the `Num`

operators `+`

, `-`

, `*`

.

```
λ: :t (+)
(+) :: Num a => a -> a -> a
λ: :t (-)
(-) :: Num a => a -> a -> a
λ: :t (*)
(*) :: Num a => a -> a -> a
```

`Integral`

is also a numeric typeclass.`Num`

includes all numbers, including reals and integral numbers, Integral includes only integral (whole) numbers. In this typeclass are Int and Integer.`Floating`

includes only floating point numbers, so Float and Double.`Fractional`

is any kind of number for which we can define a division. It’s a superset of`Floating`

.

`/`

, `mod`

are fractional, integral respectively and `^`

only supports an integral power.

```
λ: :t (/)
(/) :: Fractional a => a -> a -> a
λ: :t (mod)
(mod) :: Integral a => a -> a -> a
λ: :t (^)
(^) :: (Integral b, Num a) => a -> b -> a
```

A very useful function for dealing with numbers is `fromIntegral`

.

```
fromIntegral :: (Integral a, Num b) => a -> b
```

It takes an integral number and converts it into a more generic number to perform operations such that it works nicely with floating point numbers.