<<

Recursion and Induction: ; Types; Lists

Greg Plaxton Theory in Programming Practice, Spring 2004 Department of Computer Science University of Texas at Austin Tuples

• The is Haskell’s version of a record

• Any nonnegative number of data items (possibly of different types) can be combined together into a tuple

• Syntax: A tuple is surrounded by parentheses; the data items within the tuple are separated by commas

• Example: (3, 5, "foo", True)

• Of course, a component of a tuple can itself be a tuple – Example: (3, (5, "bar", ()), "foo", (True))

Theory in Programming Practice, Plaxton, Spring 2004 Tuples: The Special Case of a Singleton

• Note that Haskell uses parentheses for forming tuples and also for enforcing a particular order of evaluation within an expression

• Any expression x is equivalent to the singleton tuple with first (and only) component x – For example, the expressions "foo", ("foo"), and (("foo")) are all equivalent

Theory in Programming Practice, Plaxton, Spring 2004 Tuples: The Special Case of a Pair

• A tuple with two components is called a pair

• The predefined functions fst and snd are applicable to pairs, and return the first and second components of the pair, respectively – Example: fst ((1, 2, 3), True) evaluates to (1, 2, 3)

Theory in Programming Practice, Plaxton, Spring 2004 Tuples: Fibonacci Revisited

• In an earlier lecture we presented the following highly inefficient recursive program for computing the Fibonacci numbers fib 0 = 0 fib 1 = 1 fib (n + 2) = (fib n) + (fib (n + 1))

Theory in Programming Practice, Plaxton, Spring 2004 Tuples: A More Efficient Fibonacci Program

• The following fibpair provides the basis for a more efficient implementation of fib fibpair 0 = (0,1) fibpair n = (y, x + y) where (x, y) = fibpair (n - 1)

• We can then define fib as follows fib 0 = 0 fib n = snd (fibpair (n - 1))

Theory in Programming Practice, Plaxton, Spring 2004 Tuples: A Fundamental Theorem of Number Theory

• For any pair of positive integers m and n, there exist integers a and b such that a · m + b · n = gcd(m, n)

• Exercises: – Prove the above result by induction on pairs of positive integers (m, n) – Prove the above result by induction on m + n – Write a Haskell program which, given a pair of positive integers (m, n), computes a pair (a, b) satisfying the above equation

Theory in Programming Practice, Plaxton, Spring 2004 Types

• Every Haskell expression has a type – The expression ’a’ has type Char – The expression "foo" has type [Char], which denotes a list of Char; we’ll discuss lists in greater detail later – The expression "(’a’, True)" has type (Char, Bool) – The function chr has type Int -> Char; we’ll discuss function types in greater detail on the next slide

• For the most part the types are inferred by the type system, rather than being explicitly specified by the programmer

• You can ask the hugs interpreter to specify the type of any expression by typing :t followed by the expression

Theory in Programming Practice, Plaxton, Spring 2004 Types: Functions

• Each function has a type, namely, the types of its arguments in order followed by the type of the result, all separated by ->

• Example: Suppose we define the functions imply p q = not p || q digit c = (’0’ <= c) && (c <= ’9’)

• We can then ask hugs to tell us the types of these functions Main> :t imply imply :: Bool -> Bool -> Bool Main> :t digit digit :: Char -> Bool

Theory in Programming Practice, Plaxton, Spring 2004 Types: Capitalization Rule

• Type names are capitalized

• The name of a function or parameter is not capitalized

Theory in Programming Practice, Plaxton, Spring 2004 Types: Polymorphism

• A polymorphic function can accept and produce data of many different types

• Haskell allows us to write functions whose arguments can be of any type, or any type that satisfies some constraints

Theory in Programming Practice, Plaxton, Spring 2004 Types: Polymorphism Examples

• Consider the following functions identity x = x exch (x,y) = (y,x) eqpair (x,y) = x == y

• Let’s ask hugs to tell us the type of each of these functions? Main> :t identity identity :: a -> a Main> :t exch exch :: (a,b) -> (b,a) Main> :t eqpair eqpair :: Eq a => (a,a) -> Bool

Theory in Programming Practice, Plaxton, Spring 2004 Types: Another Polymorphism Example

• Consider a function that sorts the two components of a pair. sortpair (x,y) | x <= y = (x,y) | x > y = (y,x)

• The type of sortpair is Main> :t sortpair sortpair :: Ord a => (a,a) -> (a,a)

Theory in Programming Practice, Plaxton, Spring 2004 Type Classes

• Haskell has an extensive type system which we only touch upon in this course

• A type in Haskell represents a of types, each of which has a certain function (or set of functions) defined on it – The Eq type class consists of all types on which an equality operation is defined – The Ord type class consists of all types on which an order operation is defined – The Num type class consists of all types on which typical arithmetic operations (+, *, et cetera) are defined

• Type classes in functional programming are analogous to classes in in object-oriented programming, except that a type class does not have any associated data

Theory in Programming Practice, Plaxton, Spring 2004 Type Violations

• Since the interpreter can infer the type of each expression, it can automatically detect type errors Main> digit "foo" ERROR - Type error in application *** Expression : digit "foo" *** Term : "foo" *** Type : String *** Does not match : Char

Main> digit 9 ERROR - Illegal Haskell 98 class constraint in inferred type *** Expression : digit 9 *** Type : Num Char => Bool

Theory in Programming Practice, Plaxton, Spring 2004 Lists

• A list is like a tuple but all of the elements of a list are required to be of the same type

• Square brackets are used to denote a list (as opposed to parentheses for tuples)

• Of course it is possible to have a list of lists, list of tuples, tuple of lists, list of lists of lists, et cetera

• Example: The expression [(3, 5), (3,8), (3, 5)] denotes a list of pairs

• Example: The expression [[2], 3, 5, 7] is invalid because the elements are not all of the same type

• Example: The expression [] denotes the empty list

Theory in Programming Practice, Plaxton, Spring 2004 Lists: The Type of a List

Main> :t [True] [True] :: [Bool] Main> :t [True, False, True, False] [True,False,True,False] :: [Bool] Main> :t [[2],[3],[5],[7]] [[2],[3],[5],[7]] :: Num a => [[a]] Main> :t [(3,5), (3,8), (3,5), (3,7)] [(3,5),(3,8),(3,5),(3,7)] :: (Num a, Num b) => [(a,b)] Main> :t [[(3,5), (3,8)], [(3,5), (3,7), (2,9)]] [[(3,5),(3,8)],[(3,5),(3,7),(2,9)]] :: (Num a, Num b) => [[(b,a)]] Main> :t [’a’,’b’,’c’] [’a’,’b’,’c’] :: [Char]

Theory in Programming Practice, Plaxton, Spring 2004 Lists: The Cons Constructor “:”

• The cons operator is used to construct a new list from an existing one by prepending an additional

• The symbol “:”, pronounced “cons”, is used to denote this operator

• The expression x:xs denotes the list formed by prepending the element x to the list xs

Theory in Programming Practice, Plaxton, Spring 2004 Lists: Cons Examples

Main> 3: [2,1] [3,2,1] Main> 3: [] [3] Main> 1: (2: (3: [])) [1,2,3] Main> ’j’: "misra" "jmisra" Main> "j": "misra" ERROR - Type error in application *** Expression : "j" : "misra" *** Term : "j" *** Type : String *** Does not match : Char

Theory in Programming Practice, Plaxton, Spring 2004 Lists: Pattern Matching

• It is common to define a recursive function on lists by specifying the value explicitly for the empty list, and then using an inductive rule for nonempty lists

• Here is a function for computing the number of elements in a list len [] = 0 len (x:xs) = 1 + (len xs)

Theory in Programming Practice, Plaxton, Spring 2004 Lists: Sum, Product, Maximum

• Here are recursive programs for computing the sum, product, and maximum of the elements of a list suml [] = 0 suml (x:xs) = x + (suml xs)

multl [] = 1 multl (x:xs) = x * (multl xs)

maxl [x] = x maxl (x:xs) = max x (maxl xs)

Theory in Programming Practice, Plaxton, Spring 2004