Presentation is loading. Please wait.

Presentation is loading. Please wait.

4/6/20141 GC16/3011 Functional Programming Lecture 8 Designing Functional Programs (2)

Similar presentations


Presentation on theme: "4/6/20141 GC16/3011 Functional Programming Lecture 8 Designing Functional Programs (2)"— Presentation transcript:

1 4/6/20141 GC16/3011 Functional Programming Lecture 8 Designing Functional Programs (2)

2 4/6/20142 Contents Structural induction: example append Structural induction: example append Passing data between functions: isort Passing data between functions: isort Modes of recursion: tail recursion and mutual recursion Modes of recursion: tail recursion and mutual recursion Removing mutual recursion Removing mutual recursion Lazy evaluation: infinite lists Lazy evaluation: infinite lists

3 4/6/20143 Induction on Lists: append The append function takes two lists of anything and returns a single list consisting of all the elements of the first list, followed by all the element of the second list The append function takes two lists of anything and returns a single list consisting of all the elements of the first list, followed by all the element of the second list Type: Type: append :: ([*], [*]) -> [*] Possible Induction hypotheses: append (xs, (y:ys)) OR: append ((x:xs), ys) OR: append (xs, ys) to help define the general case: append ((x:xs), (y:ys)) = ????

4 4/6/20144 Induction on Lists: append Think about what each possible induction hypothesis would give you Think about what each possible induction hypothesis would give you For example, if we want to define the general case for append ([1,2,3], [4,5,6]): For example, if we want to define the general case for append ([1,2,3], [4,5,6]): append(xs, (y:ys)) gives us [2,3,4,5,6] – does that help? append((x:xs),ys) gives us [1,2,3,5,6] – does that help? append (xs, ys) gives us [2,3,5,6] – does that help?

5 4/6/20145 Induction on Lists: append Answer: use append (xs, (y:ys)) as the induction hypothesis. Thus, there is only one parameter of recursion. The general case is: Answer: use append (xs, (y:ys)) as the induction hypothesis. Thus, there is only one parameter of recursion. The general case is: append ((x:xs), (y:ys)) = x : (append (xs, (y:ys)) Or, simply: append ((x:xs), any) = x : (append (xs, any))

6 4/6/20146 Induction on Lists: append Base case (for parameter of recursion): Base case (for parameter of recursion): append ([], (y:ys)) = ???? We choose the answer to be (y:ys) append ([], (y:ys)) = (y:ys) Or, simply: append ([], any) = any

7 4/6/20147 Induction on Lists: append Final solution: Final solution: append :: ([*], [*]) -> [*] append ([], any) = any append ((x:xs), any) = x : (append (xs, any))

8 4/6/20148 Passing data between functions A functional program usually contains several (many) functions A functional program usually contains several (many) functions Focus on how data passes between those functions Focus on how data passes between those functions Example: insertion sort isort Example: insertion sort isort

9 4/6/20149 Insertion Sort (specification) Define sorted list Define sorted list An empty list is already sorted An empty list is already sorted A singleton list is already sorted A singleton list is already sorted The list (x:xs) is sorted if The list (x:xs) is sorted if x is less than all items in xs, AND x is less than all items in xs, AND xs is sorted xs is sorted NB only lists of numbers NB only lists of numbers

10 4/6/201410 Insertion Sort (strategy) Start with two lists A and B Start with two lists A and B A is the input list A is the input list B is initially empty B is initially empty One at a time, move an element from A to B One at a time, move an element from A to B Ensure that at all times B is sorted Ensure that at all times B is sorted We will need a function that can insert a number into a sorted list and return a sorted list We will need a function that can insert a number into a sorted list and return a sorted list

11 4/6/201411 Insertion Sort (design) The list B is an accumulator The list B is an accumulator So use accumulative recursion So use accumulative recursion Top-down approach: assume the function insert exists and design the rest of the program first (leap of faith!) Top-down approach: assume the function insert exists and design the rest of the program first (leap of faith!) Then design insert Then design insert

12 4/6/201412 Insertion sort (code 1) || comments… isort :: [num] -> [num] isort any = xsort any [] || comments… xsort :: [num] -> [num] -> [num] xsort [] sorted = sorted xsort (x:xs) sorted = xsort xs (insert x sorted)

13 4/6/201413 Insertion sort (code 2) Code for insert: Code for insert: || comments… insert :: num -> [num] -> [num] insert x [] = [x] insert x (y:ys) = (x:(y:ys)), if (x { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/3/780057/slides/slide_13.jpg", "name": "4/6/201413 Insertion sort (code 2) Code for insert: Code for insert: || comments… insert :: num -> [num] -> [num] insert x [] = [x] insert x (y:ys) = (x:(y:ys)), if (x

14 4/6/201414 Insertion sort (code 3) Use induction hypothesis: assume that insert x ys correctly inserts x into the list ys and produces the correct sorted list as a result: Use induction hypothesis: assume that insert x ys correctly inserts x into the list ys and produces the correct sorted list as a result: insert :: num -> [num] -> [num] insert x [] = [x] insert x (y:ys) = (x:(y:ys)), if (x { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/3/780057/slides/slide_14.jpg", "name": "4/6/201414 Insertion sort (code 3) Use induction hypothesis: assume that insert x ys correctly inserts x into the list ys and produces the correct sorted list as a result: Use induction hypothesis: assume that insert x ys correctly inserts x into the list ys and produces the correct sorted list as a result: insert :: num -> [num] -> [num] insert x [] = [x] insert x (y:ys) = (x:(y:ys)), if (x [num] -> [num] insert x [] = [x] insert x (y:ys) = (x:(y:ys)), if (x

15 4/6/201415 Modes of recursion: tail recursion mylast :: [*] -> * mylast [] = error no last item of empty list mylast (x:[]) = x mylast (x:xs) = mylast xs

16 4/6/201416 Modes of recursion: mutual recursion nasty :: [char] -> [char] nasty [] = [] nasty ((:rest) = xnasty rest nasty (x:xs) = (x : (nasty xs)) xnasty :: [char] -> [char] xnasty [] = error missing end bracket xnasty ():rest) = nasty rest xnasty (x:xs) = xnasty xs

17 4/6/201417 Removing mutual recursion skip :: [char] -> [char] skip [] = [] skip ((: rest) = skip (doskip rest) skip (x:rest) = (x : (skip rest)) doskip :: [char] -> [char] doskip [] = error missing end bracket doskip ():rest) = rest doskip (x:xs) = doskip xs

18 4/6/201418 Lazy evaluation: infinite lists Evaluate fst (24, (37 / 0)) Evaluate fst (24, (37 / 0)) Remember definition of fst: Remember definition of fst: fst :: (*,**) -> * fst (x,y) = x What does this function do? :- What does this function do? :- f x = (x : (f (x+1)))

19 4/6/201419 Infinite lists (2) Some forms of bad recursion may NOT create an infinite loop because they are evaluated ONLY AS FAR AS NECESSARY: Some forms of bad recursion may NOT create an infinite loop because they are evaluated ONLY AS FAR AS NECESSARY: f :: num -> [num] f x = (x : (f (x + 1)) main = hd (tl (f 34))

20 4/6/201420 Infinite lists (3) ones = (1 : ones) ones = (1 : ones) main = hd (tl (tl ones)) main = hd (tl (tl ones))

21 4/6/201421 Summary Structural induction: example append Structural induction: example append Passing data between functions: example isort Passing data between functions: example isort Modes of recursion: tail recursion and mutual recursion Modes of recursion: tail recursion and mutual recursion Removing mutual recursion Removing mutual recursion Lazy evaluation: infinite lists Lazy evaluation: infinite lists


Download ppt "4/6/20141 GC16/3011 Functional Programming Lecture 8 Designing Functional Programs (2)"

Similar presentations


Ads by Google