200 likes | 334 Vues
COMP313A Programming Languages. Functional Programming (7). Lecture Outline. Type checking type classes Some Haskell tricks. Polymorphism versus Operator Overloading. Use the same function name with different types Polymorphism – the same function definition
E N D
COMP313A Programming Languages Functional Programming (7)
Lecture Outline • Type checking • type classes • Some Haskell tricks
Polymorphism versus Operator Overloading • Use the same function name with different types • Polymorphism – the same function definition • Operator overloading – different function for each different type
Polymorphism first (x, y) = x list x = [x]
Operator Overloading • == • Defined for Int and …. • One for pairs (n,m) == (p,q) = (n==p) && (m==q)
Type Classes in Haskell • Underpinned by the notion of overloading • Mechanism by which overloaded functions can be given types – why? • Elem does not make sense for every possible a • How can we still have the flexibility of polymorphic types and ensure type safety • Use type classes to do this elem :: a -> [a] -> Bool elem x [] = False elem x (y:ys) = (x == y) || elem x ys
We could have: elemBool :: Bool -> [Bool] -> Bool elem x [] = False elem x (y:ys) = (x == Booly) || elemBool x ys elemInt :: Int -> [Int] -> Bool elem x [] = False elem x (y:ys) = (x == Inty) || elemInt x ys YUK!
Type Classes in HaskellOperator Overloading • Could instead make the equality function a parameter: • But this is too general • Instead • Where type a is restricted to those types which can be used with equality elem :: (a ->a->Bool) ->a -> [a] -> Bool elem :: a -> [a] -> Bool
context elemBool :: Bool -> [Bool] -> Bool elem x [] = False elem x (y:ys) = (x == y) || elemBool x ys elemInt :: Int -> [Int] -> Bool elem x [] = False elem x (y:ys) = (x == y) || elemInt x ys elem :: Eq a Þ a -> [a] -> Bool elem x [] = False elem x (y:ys) = (x == y) || elem x ys
Operator Overloading • Think of as: • the equality operator has a set of types defined for it. These are the types which can be used with the equality operator • Thus we say: • The definition of elem can be used over all types with equality • Type classes are usedto give a type to functions like elem.
Type Checking and Classes member [] y = False member (x:xs) y = x == y || member xs y The type will be? Apply the function member to an expression e, whose type is Ord b => [[b]] Eg. A list of lists of integers. Integers have an ordering partial application member e Unify the type expressions giving (without contexts) member :: [[b]] -> [b] -> Bool e::[[b]] And member e the type [b] -> Bool
Type Checking and Classes • But also have to unify the contexts (Eq [b], Ord b) i.e are the set of defined for Eq the same as the set of types defined for Ord • Now check and simplify the context • the requirements in a context, ([b], b) can only apply to type variables • need to simplify requirements like Eq [b][3, 5, 6] == [3, 5, 6] 3==3 & 5==5 & 6 == 6 instance Eq a => Eq [a] where…. • (Eq b, Ord b)
(Eq b, Ord b) Class Eq a => Ord a where …. tells us how the class is derived but not the instances Any instance of Ord is an instance of Eq but … so…. What should the unified context be…
Ord b member e :: Ord b => [b] -> Bool
Assignment hints • Some Haskell tricks
[["auckland", "pokeno", "sh1"],["pokeno", "tauranga", "sh2"], ["tauranga", "opotiki", "sh2"], ["opotiki", "gisborne", "sh2"], ["gisborne", "napier", "sh2"], [ "napier", "woodville", "sh2"]] the cons operator x:rest x:y:rest x:y:z:rest head x head y head z head (drop 1 x) [x,y,z]:rest To get the last ement in a list use “last” To get a list with all but the first element use “tail” tail rest head last rest
To make a list x:rest [x] [x,y,z] etc If x y and z are characters then the type of [x,y,z] is String [x,y,z]:rest [x,y,z] == “fred” A function to make a list out of some argument list x = [x]
Sometimes it is easier to just create an auxiliary function which accumulates the result as an argument Sometimes it is easier to build a list in reverse order Take the list “the quick brown fox” process_list text = process_list_aux text “” process_list_aux [] result = ------------ process_list_aux x:text result = process_list_aux text ----------- : versus ++