In tro duction to F unctional Programming: Lecture 4 1 In tro duction to F unctional Programming John Harrison Univ ersit y of Cam bridge Lecture 4 Recursiv e functions and recursiv e t yp es T opics co v ered: � Kinds of recursion � Num b ers as a recursiv e t yp e � New t yp es in ML � P attern matc hing � More examples: sums, lists and trees. John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 2 Recursiv e functions: factorial Recursiv e functions are cen tral to functional programming, so it's as w ell to b e clear ab out them. Roughly sp eaking, a recursiv e function is one `de�ned in terms of itself '. F or example, w e can de�ne the factorial function in mathematics as 8 < 1 if n = 0 n ! = : n � ( n � 1)! otherwise This translates directly in to ML: - fun fact n = if n = 0 then 1 else n * fact(n - 1); > val fact = fn : int -> int - fact 6; > val it = 720 : int John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 3 Recursiv e functions: Fib onacci Another classic example of a function de�ned th recursiv ely is the n mem b er of the Fib onacci sequence 1 ; 1 ; 2 ; 3 ; 5 ; 8 ; 13 ; 21 ; : : : where eac h n um b er is the sum of the t w o previous ones. 8 > 1 if n = 0 > < f ib = 1 if n = 1 n > > : f ib + f ib otherwise n � 2 n � 1 Once again the ML is similar: - fun fib n = if n = 0 then 1 else if n = 1 then 1 else fib(n - 2) + fib(n - 1); > val fib = fn : int -> int - fib 5; > val it = 8 : int - fib 6; > val it = 13 : int John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 4 Kinds of recursion Ho w do w e kno w that the ev aluation of these functions will terminate? T rivially fact 0 terminates, since it do esn't generate a recursiv e call. If w e ev aluate fact n for n > 0, w e need fact (n - 1) , then ma yb e fact (n - 2) , fact (n - 3) etc., but ev en tually , after n recursiv e calls, w e reac h the base case. This is wh y termination is guaran teed. (Though it lo ops for n < 0.) This sort of recursion, where the argumen t to the recursiv e call(s) decreases b y 1 eac h time is called primitive recursion. The function fib is di�eren t: the recursion is not primitiv e. T o kno w that fib n terminates, w e need to kno w that fib (n - 1) and fib (n - 2) terminate. Nev ertheless, w e are still sure to reac h a base case ev en tually b ecause the argumen t do es b ecome smaller, and can't skip o v er b oth 1 and 0. John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 5 Pro ofs of termination More formally , w e can turn the ab o v e in to a pr o of b y mathematical induction than fact n terminates for eac h natural n um b er n . W e pro v e that fact 0 terminates, then that if fact n terminates, so do es fact (n + 1) . 8 P : P (0) ^ ( 8 n: P ( n ) ) P ( n + 1)) ) 8 n: P ( n ) The appropriate w a y to pro v e fib n terminates for all natural n um b ers n is to use the principle of wel lfounde d induction , rather than step-b y-step induction. 8 P : ( 8 n: ( 8 m: m < n ) P ( m )) ) P ( n ) ) 8 n: P ( n ) There is th us a close parallel b et w een the kind of r e cursion used to de�ne a function and the kind of induction used to reason ab out it, in this case sho w that it terminates. John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 6 The naturals as a recursiv e t yp e The principle of mathematical induction sa ys exactly that ev ery natural n um b er is generated b y starting with 0 and rep eatedly adding one, i.e. applying the successor op eration S ( n ) = n + 1. If w e regard the natural n um b ers as a set or a t yp e, then w e ma y sa y that it is generated b y the c onstructors 0 and S . Moreo v er, eac h natural n um b er can only b e generated in one w a y lik e this: w e can't ha v e S ( n ) = 0, and if p times q times z }| { z }| { S ( S ( � � � ( S (0)) � � � )) = S ( S ( � � � ( S (0)) � � � )) then p = q . The second prop ert y is equiv alen t to sa ying that S is inje ctive . In suc h cases the set or t yp e is said to b e fr e e , b ecause there are no relationships forced on the elemen ts. John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 7 New t yp es in ML ML allo ws us to de�ne new t yp es in just this w a y . W e write: - datatype num = O | S of num; > datatype num con O = O : num con S = fn : num -> num This declares a completely new t yp e called num and the appropriate new constructors. But in order to de�ne functions lik e fact w e need to b e able to tak e n um b ers apart again, i.e. go from S(n) to n . W e ha v en't got something lik e subtraction here. John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 8 Prop erties of t yp e constructors All t yp e constructors arising from a datatype de�nition ha v e three k ey prop erties, whic h w e can illustrate using the ab o v e example. 1. They are exhaustiv e, . ev ery elemen t of the new t yp e is obtainable either b y O or as S x for some x . 2. They are injectiv e, i.e. an equalit y test S x = S y is true if and only if x = y . 3. They are distinct, i.e. their ranges are disjoin t. More concretely this means in the ab o v e example that S(x) = O is false whatev er x migh t b e. Because of these prop erties, w e can de�ne functions, including recursiv e ones, b y p attern matching . John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 9 P attern matc hing | ho w W e p erform pattern matc hing b y using more general expressions called varstructs as the argumen ts in fn => ... or fun => ... expressions. Moreo v er, w e can ha v e sev eral di�eren t cases to matc h against, separated b y | . F or example, here is a test for whether something of t yp e num is zero: - fun iszero O = true | iszero (S n) = false; > val iszero = fn : num -> bool - iszero (S(S(O))); > val it = false : bool - iszero O; > val it = true : bool This function has the prop ert y , naturally enough, that when applied to O it returns true and when applied to S x it returns false . John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 10 P attern matc hing | wh y Wh y is this v alid? 1. The constructors are distinct , so w e kno w that there is no am biguit y . The cases for O and S x don't o v erlap. 2. The constructors are injectiv e, so w e can alw a ys reco v er x from S x if w e w an t to use x in the b o dy of that clause. 3. The constructors are exhaustive , so w e kno w that if w e ha v e a case for eac h constructor, the function is de�ned ev erywhere on the t yp e. John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
In tro duction to F unctional Programming: Lecture 4 11 Non-exhaustiv e matc hing In fact, w e can de�ne partial functions that don't co v er ev ery case. Here is a `predecessor' function. - fun pred (S(n)) = n; ! Toplevel input: ! fun pred (S(n)) = n; ! ^^^^^^^^^^^^^^^ ! Warning: pattern matching is not exhaustive > val pred = fn : num -> num The compiler w arns us of this fact. If w e try to use the function on an argumen t not of the form S x , then it will not w ork: - pred O; ! Uncaught exception: ! Match John Harrison Univ ersit y of Cam bridge, 22 Jan uary 1998
Recommend
More recommend