Download Slides

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

* Your assessment is very important for improving the workof 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