- Many programming languages have some form of overloading.
- Often limited to built-in operators:
- Equality tests for all basic types.
- Numeric operators for integers and floating point numbers.

- In some languages you can define your own overloaded functions:
- Just define two or more functions with the same name, but different types.

- Haskell takes this a step further…

`:t (*)`

(*) :: Num a => a -> a -> a`let square x = x * x`

`:t square`

square :: Num a => a -> a- The new function "inherits" the overloading of the operator…
- The function will work on
`square`*any*type in theclass, even types that haven't been defined yet!**Num** - As a more illustrative example, consider
`sort`**::****Ord**`a`**=>**[`a`]**->**[`a`]

- that "inherts" the overloading of the operator…
`<=`

- A
*type class*declares a set of*methods*, i.e. a set of related overloaded functions and operators. - Here is the definition of the predefined class:
**Num****class****Num**`a`**where**(`+`), (`*`), (`-`)**::**`a`**->**`a`**->**`a``negate`,`abs`,`signum`**::**`a`**->**`a``fromInteger`**::****Integer****->**`a`-- ...

- An
*instance declaration*provides implementations of methods for a specific type:**instance****Num****Int****where**-- ...**instance****Num****Integer****where**-- ...**instance****Num****Double****where**-- ...**instance****Num****Float****where**-- ...

- Note: in spite of the similar terminology, type classes in Haskell are for overloading, not for objects, like in object oriented languages.

**class****Eq**`a`**where**(`==`), (`/=`)**::**`a`**->**`a`**->****Bool**`a``/=``b`**=**`not`(`a``==``b`) -- default implementation`a``==``b`**=**`not`(`a``/=``b`) -- default implementation**instance****Eq****Int****where**-- ...**instance****Eq****Double****where**-- ...**instance****Eq****Char****where**-- ... -- There are instances for almost all predefined types- Quiz: which types do
*not*support equality tests?

- Example of how to define an instance of class
**Eq** **data****TrafficLight****=****Red****|****Yellow****|****Green****instance****Eq****TrafficLight****where****Red**`==`**Red****=****True****Yellow**`==`**Yellow****=****True****Green**`==`**Green****=****True****_**`==`**_****=****False**

**instance**(**Eq**`a`,**Eq**`b`)**=>****Eq**(`a`,`b`)**where**(`x1`,`y1`)`==`(`x2`,`y2`)**=**`x1``==``x2``&&``y1``==``y2`- Pairs can be tested for equality if both parts can be tested for equality.
- Similarly for larger tuples.
- Note: this definition
*is not*recursive.

**instance****Eq**`a`**=>****Eq**[`a`]**where**[]`==`[]**=****True**`x`**:**`xs``==``y`**:**`ys`**=**`x``==``y``&&``xs``==``ys`**_**`==`**_****=****False**- List can be tested for equality if the elements can be tested for equality
- Note: this definition
*is*recursive.

**class****Eq**`a`**=>****Ord**`a`**where**(`<`), (`<=`), (`>`), (`>=`)**::**`a`**->**`a`**->****Bool**`compare`**::**`a`**->**`a`**->****Ordering**`max`,`min`**::**`a`**->**`a`**->**`a`**data****Ordering****=****LT****|****EQ****|****GT**- There are instances for almost all predefined types.
- is a
**Ord***subclass*of.**Eq**- All types that are in the class are also in the
**Ord**class.**Eq** - It is expected that when returns
`x``==``y`, then**True**returns`compare``x``y`.**EQ**

- All types that are in the

**class****Enum**`a`**where**`pred`,`succ`**::**`a`**->**`a``toEnum`**::****Int****->**`a``fromEnum`**::**`a`**->****Int**`enumFrom`**::**`a`**->**[`a`]`enumFromTo`**::**`a`**->**`a`**->**[`a`] -- ...- It's enough to define and
`fromEnum`, the other methods have default implementations.`toEnum` - Instances: ,
**Bool**,**Int**,**Integer**,**Float**, …**Double**

Enum

[1

**..**5]`==`[1,2,3,4,5][1

**..**]`==`[1,2,3,4,5,`…`]['a'

**..**'g']`==`"abcdefg"- -- watch out for rounding errors…
[0.5

**..**3]`==`[0.5,1.5,2.5,3.5] - This is syntactic sugar for the methods of the class:
**Enum**[

`x`**..**`y`]`==``enumFromTo``x``y`[

`x`**..**]`==``enumFrom``x`

**class****Bounded**`a`**where**`minBound`,`maxBound`**::**`a`- Instances: ,
**Bool**,**Char**, tuples**Int** - Not bounded:
**Integer** - Example:
`enumAll`**::**(**Bounded**`a`,**Enum**`a`)**=>**[`a`]`enumAll`**=**[`minBound`**..**`maxBound`]

**class****Show**`a`**where**`show`**::**`a`**->****String**-- some more functions...**class****Read**`a`**where**`read`**::****String****->**`a`-- some more functions...- There are instances for almost all predefined types.
- Note that for , which instance is used depends
`read`*not*on the type of the argument, but on how the result is used.

- For many predefined classes, in particular ,
**Eq**,**Ord**,**Show**,**Read**and**Enum**, there is a standard way to define instances.**Bounded** - The Haskell compiler knows how to define these instances.
- So, when you define a new data type, you can get instances for free!
**data****Suit****=****Spades****|****Hearts****|****Diamonds****|****Clubs****deriving**(**Eq**,**Ord**,**Show**,**Read**,**Enum**,**Bounded**)

dataSuit=Spades|Hearts|Diamonds|Clubsderiving(Eq,Ord,Enum,Bounded)instanceShowSuitwhereshowSpades="♠"showHearts="♥"showDiamonds="♦"showClubs="♣"

dataRank=NumericInt|Jack|Queen|King|Acederiving(Eq,Ord)instanceShowRankwhereshow(Numericn)=shownshowJack="J"showQueen="Q"showKing="K"showAce="A"

**data****Card****=****Card**{`rank`**::****Rank**,`suit`**::****Suit**}**instance****Show****Card****where**`show`(**Card**`r``s`)**=**`show``r``++``show``s`- Quiz: is this a recursive definition?

**data****Hand****=****Empty****|****Add****Card****Hand****instance****Show****Hand****where**`show`**Empty****=**"."`show`(**Add**`c``h`)**=**`show``c``++`" "`++``show``h`- Quiz: is this a recursive definition?

- With

:**deriving****Show**`example_hand_2`

Add (Card {rank = Ace, suit = Spades}) (Add (Card {rank = King, suit = Clubs}) Empty)

- With the hand-written instances:
**Show**`example_hand_2`

A♠ K♣

- A class to enumerate all the values of "small" types.
**class****Small**`a`**where**`values`**::**[`a`]

- Some instances:
**instance****Small****Bool****where**`values`**=**[**False**,**True**]**instance****Small****Suit****where**`values`**=**[`maxBound`**..**`minBound`]**instance****Small****Rank****where**`values`**=**(`...`)**instance****Small****Card****where**`values`**=**[**Card**`r``s`**|**`s`**<-**`values`,`r`**<-**`values`]

**class****AlwaysTrue**`prop`**where**`alwaysTrue`**::**`prop`**->****Bool****instance****AlwaysTrue****Bool****where**`alwaysTrue``b`**=**`b`**instance**(**Small**`a`,**AlwaysTrue**`prop`)**=>****AlwaysTrue**(`a`**->**`prop`)**where**`alwaysTrue``f`**=**`and`[`alwaysTrue`(`f``x`)**|**`x`**<-**`values`]- Exhaustive testing of functions is better than random testing!
- Unfortunately it's only practical when the argument types are sufficiently small…

- Consider
`f`**::****String****->****String**`f``s`**=**`show`(`read``s`)

- Will this work? Compare with
`square`**::****Num**`a`**=>**`a`**->**`a``square``x`**=**`x``*``x`

- Definitions without arguments and without type signatures are not allowed
to be overloaded. This is called
*the monomorphism restriction*.`answer`**=**6`*`7

- Numeric literals are overloaded, so you would expect
, but one specific type will be chosen depending on how you use
`answer`**::****Num**`a`**=>**`a`.`answer` - If nothing else determines which type
`answer`

should have,*defaulting*rules specific for theclass kick in, and you get**Num**.`answer`**::****Integer** - For code entered directly GHCi, the monomorphism restriction is not used, and there are extended defaulting rules to avoid ambiguities.

- Haskell has a lot in common with preceding functional languages, notably Miranda, Standard ML and Lazy ML.
**Type classes**was the main novel feature in Haskell.- Type classes were primarily intended as an improvement over how Standard ML handled equality and numeric operators.
- Then type classes got extended (with constructor classes, multi-parameter classes, functional depdendencies, …) and are now used for a lot more things than anyone anticipated.
- But David Turner (creator of Miranda) thinks type classes were a mistake :-)

- Standard ML has one built-in type class for equality
(

`==`)**::**''a -> ''a -> Bool

- Predefined numeric operators are overloaded,
(

`*`)**::****Int****->****Int****->****Int**(`*`)**::****Double****->****Double****->****Double**

- but user-defined numeric functions have to choose one specific type.

- We talk about classes, instances and methods in Haskell, so at first sight, type classes in Haskell might seem similar to classes in object oriented languages.
- But they serve different purposes.
- Type classes in Haskell are used to introduce overloaded functions.
- Classes in object oriented languages are used to describe objects…