with Interpreters

and Functional Programming

Chapter 22

Overloading and Type Classes

**H. Conrad Cunningham**

**5 November 2018**

Copyright (C) 2017, 2018, H. Conrad Cunningham

**Acknowledgements**: I originally created these slides in Fall 2017 to accompany what is now Chapter 22, Overloading and Type Classes, in the 2018 version of the textbook *Exploring Languages with Interpreters and Functional Programming*.

**Browser Advisory**: The HTML version of this document may require use of a browser that supports the display of MathML. A good choice as of November 2018 is a recent version of Firefox from Mozilla.

**Source Code**: The Haskell module for this chapter is in file `TypeClassMod.hs`

.

Motivate overloading and type classes

Introduce type class laws

Extend concepts to inheritance and multiple constraints

Compare Haskell to other languages

*Parametric polymorphism*— same name, same function definition for all types of arguments/results — “polymorphism”*Overloading*— same name, same functionality, but different function definitions depending upon type`(+)`

function takes two numbers of same type

```
elemBool :: Bool -> [Bool] -> Bool
elemBool x [] = False
elemBool x (y:ys) = eqBool x y || elemBool x ys
```

How can define `eqBool`

?

```
eqBool :: Bool -> Bool -> Bool
eqBool True False = False
eqBool False True = False
eqBool _ _ = True
```

*Not general!*

`eqBool`

```
elemGen :: (a -> a -> Bool) -> a -> [a] -> Bool
elemGen eqFun x [] = False
elemGen eqFun x (y:ys) = eqFun x y || elemGen eqFun x ys
elemBool :: Bool -> [Bool] -> Bool
elemBool = elemGen eqBool
```

But

`elemGen`

*too general!*any`a -> a -> Bool`

Equality meaningless for some types (functions?)

Overload

`==`

operator for set of typesRestrict polymorphism in

`elem`

to types with`(==)`

definedIntroduce

**type class**for equality, then constrain polymorphism to that**context**(used before)

Define class

`Eq`

as set of types with`(==)`

definedMake type

`Bool`

**instance**of class (also others like`Int`

,`Char`

)

Make list in

`Eq`

if element is alsoLeft side of equation defined by right side

Right side must be previously defined operation

(e..g.`x == y`

) or terminating recursion (e.g.`xs == ys`

)

```
class Eq a where -- from Prelude library
(==), (/=) :: a -> a -> Bool
-- Minimal complete definition: (==) or (/=)
x /= y = not (x == y)
x == y = not (x /= y)
```

- Must
*override*(redefine) at least one to break cycle above

Equality is

**equivalence relation**in math. For all`x`

,`y`

, and`z`

in type’s set:**Reflexivity**:`x == x`

is`True`

.**Symmetry**:`x == y`

if and only if`y == x`

.**Transitivity**: if`x == y`

and`y == z`

, then`x == z`

.

`x /= y`

equivalent to`not (x == y)`

**Type class laws**— must hold for all`Eq`

instancesReality intervenes!

`x == x`

for infinite? floating?

```
class Visible a where
toString :: a -> String
size :: a -> Int
instance Visible Char where
toString ch = [ch]
size _ = 1
instance Visible Bool where
toString True = "True"
toString False = "False"
size _ = 1
instance Visible a => Visible [a] where
toString = concat . map toString
size = foldr (+) 1 . map size
```

`Visible`

No constraints on the conversion to strings

`size`

must return`Int`

, finite and bounded

`Ord`

is**subclass**of`Eq`

```
class Eq a => Ord a where -- from Prelude
(<), (<=), (>), (>=) :: a -> a -> Bool
max, min :: a -> a -> a
-- Minimal complete definition: (<) or (>)
-- Must break circular definition
x <= y = x < y || x == y
x < y = y > x
x >= y = x > y || x == y
x > y = y < x
max x y | x >= y = x
| otherwise = y
min x y | x <= y = x
| otherwise = y
```

`Ord`

For

`<=`

and all`x`

,`y`

,`z`

in type’s set (**total order**)**Reflexivity**:`x <= x`

is`True`

**Antisymmetry**:`x <= y`

and`y <= x`

, then`x == y`

**Transitivity**: if`x <= y`

and`y <= z`

, then`x <= z`

**Trichotomy**(comparability, totality):`x <= y`

or`y <= x`

`==`

(and`/=`

) satisfy`Eq`

type class laws`<`

,`>`

,`>=`

,`max`

, and`min`

satisfy definition in declaration

`isort`

`instance`

`==`

overloaded from different instances

`class`

`OrdVis`

has**multiple inheritance**— reuse methods of bothMust satisfy type class laws for

`Ord`

and`Visible`

Prelude classes in Section 6.3 of the Haskell 2010 Language

Typeclassopedia by Brent Yorgey

Haskell class is collection of types; Java class similar to type

Haskell class similar to Java abstract class except Haskell has no data, Java only single inheritance

Haskell class similar to Java interface except Haskell has default method definitions (in Java from Java 8)

Haskell instance is type, not object — like concrete Java class that extends abstract classes or implements interface

Haskell separates type definition from method definition; Java mixes type and method definition

Haskell class methods correspond to Java instance methods

Each instance provides own definition for methods; class defaults correspond to default definitions in parent class

Haskell has no receiver object or mutable fields

Haskell class methods bound statically at compile time; Java bound dynamically at runtime

Java attaches identifying information to runtime object; Haskell only attaches logically

Haskell does not support Java/C++ overloading where functions have different types, same name

Haskell objects cannot be implicitly coerced, types have no default parent — Java has universal base class

`Object`

(reference types)Haskell class separates type from access control, uses modules for access control — Java mixes

First appeared in Haskell, but adopted in newer languages

Rust supports traits, limited form of type classes

Scala’s implicit classes/parameters enable similar type enrichment idiom

PureScript supports Haskell-like type classes

Idris supports interfaces, generalization of Haskell type classes

JavaScript has functional libraries such as Ramda

Overloading function giving same name, “same functionality” but different definitions for different types

Type classes and instances

Type class laws to define “same functionality”

Multiple constraints, inheritance

Comparison to classes in other languages

The Haskell code for this chapter is file `TypeClassMod.hs`

.