functional programming lecture 9 - type overloading and type classes
DESCRIPTION
Functional Programming Lecture 9 - type overloading and type classes. Type Polymorphism. A function is polymorphic if it has many types. E.g. length :: [Char] -> Int length :: [Int] -> Int length :: [[Int]] -> Int - PowerPoint PPT PresentationTRANSCRIPT
1
Functional ProgrammingLecture 9 -
type overloading and type classes
2
Type Polymorphism
A function is polymorphic if it has many types.
E.g. length :: [Char] -> Int
length :: [Int] -> Int
length :: [[Int]] -> Int
Polymorphism is only appropriate when the function has a single definition (e.g. length x:xs = 1 + length xs, etc.) which works over all types.
To define a polymorphic function, we use a type variable:
length :: [a] -> Int
3
Type Overloading
Type overloading is used when a function has a variety of types and different definitions are used for different types.
E.g. check whether an element is a member of a list.
elemBool :: Bool -> [Bool] -> Bool
elemBool x [] = False
elemBools x (y:ys) = (x ==Bool y) || elemBool x ys
elemInt :: Int -> [Int] -> Bool
would differ only in its use of ==Int instead of ==Bool .
Clearly these equalities are different, e.g.
True ==Bool False = False
True ==Bool True = True
...
0 ==Int 0 = True
(m+1) ==Int (n+1) = m ==Int n
4
Type Overloading
One solution:
make the equality function a parameter of the general function
elemGen :: (a -> a -> Bool) -> a -> [a] -> Bool
Alternative solution:
define a function which uses the overloaded equality
elem :: a -> [a] -> Bool
But restricts a to types which have an equality.
This is more
- readable
- amenable to reuse.
Type classes are the mechanism which allow us to define functions like elem with type requirements.
5
Type Classes
The Equality class
class Eq a where
(==) :: a -> a -> Bool
Many built-in types are instances of Eq:
Float, Int, Bool, Char, tuples and lists. E.g. if a is Int then == is ==Int.
To use a type class, we insert a context into a type.
E.g. elem :: (Eq a) => a -> [a] -> Bool
(Eq a) => is called the context. It expresses a requirement of the type a, namely, it must have an equality operator.
6
ExamplesCheck 3 values are equal.
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z = (x == y) && (y == z)
So,• we can check Integers:
allEqual 1 2 3 which returns False, because
Int is an Eq type and therefore
allEqual :: Int -> Int -> Int -> Bool
• we can check pairs of Integers and Characters:
allEqual (1,’a’) (1,’a’) (1’a’) which returns True, because
tuples of Int and Char is an Eq type (because both Int and Char are Eq types) and therefore
allEqual :: (Int,Char) -> (Int ,Char) ->(Int ,Char) ->
Bool
7
But, we cannot compare functions from Int to Int with allEqual
Assume
succ :: Int -> Int
succ x = x+1
What happens when we evaluate
allEqual succ succ succ ?
We get a type error:
ERROR: Int -> Int is not an instance of class “Eq”
because (Int -> Int) is not a member of the class Eq,
in other words, we have not defined == on functions!
Make sure you understand this -- it is quite likely that you will see this kind of error often!
Note: type of allEqual (succ x) (succ x) (succ x)?
8
More type classes
You can define your own type classes (unlikely in this course), and use further built-in ones (more likely!).
3 most common classes:
Eq
class Eq a where
(==), (/=) :: a-> a -> Bool
x /= y = not (x == y)
x == y = not (x/= y)
Ord
class (Eq a)=> Ord a where
<, >, <=, >= :: a -> a -> Bool
max, min :: a -> a -> a
max x y
| x >= y = x
| otherwise = y
etc.
Class Ord includes class Eq!
9
Show
class Show a where
show :: a -> String
most types belong to this class, even functions which are displayed as <<function>>.
Reminder: a type context uses the symbol =>
a type uses the symbol ->
E.g. elem :: Eq a => a -> [a] -> Bool