Download Slides

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Cse536 Functional Programming
Lecture #11, Nov. 01, 2004
•Special Guest lecture by Tom Harke
•Today’s Topics
–The Haskell Class system
–Instance declarations
–Inheritance and dependent classes
–Derived instances
–The Show class
–The Fix operator from homework # 5
•Reading Assignment
–Chapter 12 - Qualified Types
–Appendix - A Tour of Haskell’s Standard Type Classes
Sections 24.4 & 24.5
The Show and Read Class (pp 334-340)
•Reminder - Mid-Term Exam Wednesday - next class meeting!
– open book exam
5/24/2017
1
Cse536 Functional Programming
The Haskell Class System
• Think of a Qualified type as a type with a Predicate
• Types which meet those predicates have "extra"
functionality.
• A class definition defines the type of the "extra"
functionality.
• An instance declarations defines the "extra"
functionality for a particular type.
5/24/2017
2
Cse536 Functional Programming
Example Class Definition
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y
= not (x==y)
Note default
definition of (/=)
class (Eq a) => Ord a where
compare
:: a -> a -> Ordering
(<), (<=), (>=), (>) :: a -> a -> Bool
max, min
:: a -> a -> a
5/24/2017
3
Cse536 Functional Programming
Properties of a class definition
class (Eq a) => Ord a where
compare
:: a -> a -> Ordering
(<), (<=), (>=), (>) :: a -> a -> Bool
max, min
:: a -> a -> a
• Class name is capitalized, think of this as the name
of a type predicate that qualifies the type being
described.
• Classes can depend on another class or in other
words require another classes as a prerequisite
• The methods of a class are functions whose type
can depend upon the type being qualified
• There can be more than one method.
• The methods can be ordinary (prefix) functions or
infix operators.
5/24/2017
4
Cse536 Functional Programming
First Example
• Example:
– The Class Eq
– Concrete Types without arrows (functions -> ) support equality.
– Assume basic equalities: int_eq, string_eq, bool_eq
• Make the following tree like data types that represent arithmetic
expressions, instances of class Eq
data Aop = Add | Sub | Mult | Div
data Aexp = Num Int | Exp (Aexp, Aop, Aexp)
5/24/2017
5
Cse536 Functional Programming
First define equality functions
aop_eq
aop_eq
aop_eq
aop_eq
aop_eq
Add Add = True
Sub Sub = True
Mult Mult = True
Div Div = True
_ _ = False
aexp_eq (Num x) (Num y) = int_eq x y
aexp_eq (Exp(e1,x,e2))(Exp(f1,y,f2))
= (aexp_eq e1 f1) &&
(aop_eq x y) &&
(aexp_eq e2 f2)
aexp_eq _ _ = False
5/24/2017
6
Cse536 Functional Programming
Then make Instance Definitions
• To make an instance
instance Eq(Aop) where
x == y = aop_eq x y
x /= y = not(aop_eq x y )
instance Eq(Aexp) where
x == y = aexp_eq x y
x /= y = not(aexp_eq x y )
• Example use
? (Num 3) == (Num 5)
False
? (Num 3) == (Num (5-2))
True
5/24/2017
7
Cse536 Functional Programming
Another Example: Num Complex
• Make Complex numbers an instance of class Num.
data Complex = C Float Float
– An instance of Num, must first be an instance of Eq and Show and
provide methods for (+), (-), and (*) (amongst others).
First provide the numeric operators
complex_add (C x y) (C a b) = C (x+a) (y+b)
complex_sub (C x y) (C a b) = C (x-a) (y-b)
complex_mult (C x y) (C a b)
= C (x*a - y*b) (x*b + a*y)
5/24/2017
8
Cse536 Functional Programming
Num Instance
Then make the instance declarations
instance Eq(Complex) where
(C x y) == (C a b) = x==a && y==b
instance Show(Complex) where
showsPrec = error "No show for complex"
showList = error "No show for complex"
instance Num(Complex) where
x + y = complex_add x y
x - y = complex_sub x y
x * y = complex_mult x y
• Note that the Show instance is quite imprecise, but this will
cause an error only if it is ever used
5/24/2017
9
Cse536 Functional Programming
Full Num Class
class (Eq a, Show a) => Num a where
(+), (-), (*) :: a -> a -> a
negate
:: a -> a
abs, signum
:: a -> a
fromInteger
:: Integer -> a
fromInt
:: Int -> a
x - y
fromInt
5/24/2017
= x + negate y
= fromIntegral
10
Cse536 Functional Programming
Class Ord
• The Class Ord is interesting for several reasons
– It’s a dependant Class, so it uses inheritance
Class Eq a => Ord a where ...
– It makes extensive use of default method definitions
• Example: Eq Tree => Ord Tree
data Tree a = Leaf a | Branch (Tree a) (Tree a)
– First make Tree an instance of Eq
instance Eq a => Eq (Tree a) where
(Leaf x) == (Leaf y) = x==y
(Branch x y) == (Branch a b) = x==a && y==b
_ == _ = False
5/24/2017
11
Cse536 Functional Programming
Make Tree an instance of Ord
• First define a (<) and (<=) function for Tree Int
instance (Ord a,Eq a) => Ord(Tree a) where
(Leaf _) < (Branch _ _) = True
(Leaf x) < (Leaf y)
= x < y
(Branch _ _) < (Leaf _) = False
(Branch l1 r1) < (Branch l2 r2)
= if l1==l2
then r1 < r2
else l1 < l2
t1 <= t2 = t1 < t2 || t1 == t2
is Eq a really necessary as a dependent type?
5/24/2017
12
Cse536 Functional Programming
Full Definition of Ord
class (Eq a) => Ord a where
compare
:: a -> a -> Ordering
(<), (<=), (>=), (>)
:: a -> a -> Bool
max, min
:: a -> a -> a
compare x y | x==y
= EQ
| x<=y
= LT
| otherwise = GT
x <= y
= compare x y /= GT
x < y
= compare x y == LT
x >= y
= compare x y /= LT
x > y
= compare x y == GT
max x y
| x >= y
= x
| otherwise
= y
min x y
| x <= y
= x
| otherwise
= y
An instance need only provide enough methods to define the others.
Here compare would be enough or just <= plus Eq a
5/24/2017
13
Cse536 Functional Programming
A closer look. Classes for Type Constructors
• How do classes work for type constructors like Tree
and [-]
• Consider:
data Mylist a = Nil | Cons a (Mylist a)
int_list_eq(Nil, Nil) = True
int_list_eq(Cons x xs, Cons y ys) =
(int_eq x y) && (int_list_eq(xs,ys))
int_list_eq (_, _) = False
list_eq :: (a -> a -> Bool) -> (Mylist a,Mylist
list_eq f (Nil, Nil) = True
list_eq f (Cons x xs, Cons y ys) =
(f x y) && (list_eq f (xs, ys))
list_eq f (_, _) = False
5/24/2017
a) -> Bool
14
Cse536 Functional Programming
Classes for Type Constructors
• The function list_eq motivates the following
Dependent instance.
instance Eq a => Eq(Mylist a) where
Nil == Nil
= True
(Cons x xs) == (Cons y ys) = (x == y) && (xs == ys)
_ == _
= False
? Nil == (Cons 2 Nil)
False
? (Cons 2 Nil) == (Cons (3-1) Nil)
True
What type is (==) used at?
What type is (==) used at?
5/24/2017
15
Cse536 Functional Programming
Think about this!
• Consider :
data Bush a = One a
| Two (Bush a) (Bush a)
| Many [Bush a]
instance Eq a => Eq(Bush a) where
(One x) == (One y) = (x == y)
(Two x1 x2) == (Two y1 y2) = (x1 == y1) && (x2 == y2)
(Many xs) == (Many ys) = (xs == ys)
_ == _ = False
? Many [One 2] == Many [One 2, Two (One 3) (One 5)]
False
? Many [One 3] == Many [One 3]
True
5/24/2017
16
Cse536 Functional Programming
Analyze
instance
Eq a => Eq(Bush a) where
(One x) == (One y)
= (x == y)
(Two x1 x2) == (Two y1 y2)
= (x1 == y1) && (x2 == y2)
(Many xs) == (Many ys) = (xs == ys)
_ == _
= False
•
•
•
•
•
(==) :: a -> a -> Bool
(==) :: Bush a -> Bush a -> Bool
(==) :: Bush a -> Bush a -> Bool
(==) :: [ Bush a ] -> [ Bush a ] -> Bool
How do we get (==) ?
5/24/2017
17
Cse536 Functional Programming
The Class Show
• Instances of the Class Show are those types that
can be converted to character strings
show :: Show a => a -> String
• Example uses:
show (2+2)
show (not (3=4))
---> “4”
---> “True”
Using show and concatenation (++)
“My name is” ++ show name ++ “I am” ++
show age ++ “years old”
• (++) is right associative so this runs in linear time
5/24/2017
18
Cse536 Functional Programming
Show and Trees
• If we try and define a show function for trees we lose
this linear time property. Consider a simplification of
Class Show (see the appendix for the real definition):
Instance Show a => Show (Tree a) where
show (Leaf x) = “(Leaf ” ++ show x ++ “)”
show (Branch x y) =
“(Branch” ++ show x ++ show y ++ “)”
When we Show the left sub-tree x, and the right subtree y, we end re-concatenating the string returned
by the “recursive” call.
5/24/2017
19
Cse536 Functional Programming
Restoring Linearity
• Suppose we had a function shows
shows :: Show a => a -> String -> String
• And shows was part of the Show Class as well.
Class Show a where
show :: a -> String
shows :: a -> String -> String
– Where shows has an extra String argument
– Think of this argument as an accumulating parameter, that holds
all of the string printed so far.
showsTree :: Show a => Tree a -> String -> String
showsTree (Leaf x) s = “(Leaf ” ++ show x ++ “)” ++ s
showsTree (Branch x y) s =
“(Branch” ++ (showsTree x (showsTree y (“)” ++ s)))
5/24/2017
20
Cse536 Functional Programming
show can be defined in terms of shows
• showTree tree = showsTree tree “”
• Exercise: write the function
showsList :: Show a => [a] -> String -> String
showsList [] s
= ...
showsList (x:xs) s = ...
5/24/2017
21
Cse536 Functional Programming
Derived Instances
• Some Classes are so useful and so simple to define,
that we’d like the compiler to do it for us.
• Example derivable Classes:
– Eq
– Ord
– Show
• Example Uses of deriving classes
data Color = Red | Orange | Yellow | Green
| Blue |Indigo | Violet
deriving Show
data Exp = Int Int | Plus Exp Exp | Minus Exp Exp
deriving (Eq,Show)
5/24/2017
22
Cse536 Functional Programming
Type propagation in the Class System
• Class information propagates from the use of
functions with qualified types into the functions they
are used to define:
• Example:
member x [] = False
member x (z:zs) =
if x==z then True else member x zs
• Note that the type of (==)
(==) :: Eq a => a -> a -> Bool
has propagated into the type of member
member :: Eq a => a -> [a] -> Bool
5/24/2017
23
Cse536 Functional Programming
Implicit invariants of Type Classes
• When we define a type class (especially those with
multiple methods) we often want some things to be
true about the way the methods interact.
• In Haskell we can’t make these invariants explicit
• E.g.
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y
= not (x==y)
Invariants
a == b => b == a
a === a
a == b && b == c => a == c
5/24/2017
24
Cse536 Functional Programming
Another Invariant example
class (Eq a) => Ord a where
compare
:: a -> a -> Ordering
(<), (<=), (>=), (>) :: a -> a -> Bool
max, min
:: a -> a -> a
• Invariants
– Exactly one of the following is true for all x,y::a
1) x < y
2) x == y
3) x > y
• Transitivity
x <= y &&
5/24/2017
y <= z
=>
x <= z
25
Cse536 Functional Programming
The fix point operator
fix :: (a -> a) -> a
fix f = f ( fix f )
• By unrolling the definition of fix we see
fix f = f (
f ( fix f ) )
We get repeated application of f. In fact we get infinite
repeated application of f
• Instantiate the type of fix at (b -> c) . We get:
fix :: ((b->c) -> (b->c)) -> (b -> c)
5/24/2017
26
Cse536 Functional Programming
Use the eta rule
fix :: ((b->c) -> (b->c)) -> (b -> c)
fix f :: b -> c
-- for appropriate f
We can eta-expand the definition of fix
fix f n = f (fix f) n
5/24/2017
27
Cse536 Functional Programming
Example use
f fact n = if n=0
then 1
else fact(n-1) * n
note f is not recursive
factorial n = fix f n
fix f n =
f (fix f) n
if n=0 then
if n=0 then
if n=0 then
else
5/24/2017
=
1 else (fix f)(n-1) * n =
1 else f (fix f) (n-1) * n =
1
if (n-1)=0
then 1
else (fix f) (n-2) * n
28
Related documents