gc16/3011 functional programming lecture 8 designing functional programs (2)

Post on 05-Feb-2016

37 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

GC16/3011 Functional Programming Lecture 8 Designing Functional Programs (2). Contents. Structural induction: example “append” Passing data between functions: “isort” Modes of recursion: tail recursion and mutual recursion Removing mutual recursion Lazy evaluation: infinite lists. - PowerPoint PPT Presentation

TRANSCRIPT

04/22/2304/22/23 11

GC16/3011 Functional ProgrammingLecture 8

Designing Functional Programs (2)

04/22/2304/22/23 22

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 Modes of recursion: tail recursion and

mutual recursionmutual recursion Removing mutual recursionRemoving mutual recursion Lazy evaluation: infinite listsLazy evaluation: infinite lists

04/22/2304/22/23 33

Induction on Lists: “append”

The “append” function takes two lists of anything and The “append” function takes two lists of anything and returns a single list consisting of all the elements of the returns a single list consisting of all the elements of the first list, followed by all the element of the second listfirst 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)) = ????

04/22/2304/22/23 44

Induction on Lists: “append”

Think about what each possible induction hypothesis Think about what each possible induction hypothesis would give youwould give you

For example, if we want to define the general case for For example, if we want to define the general case for append ([1,2,3], [4,5,6]):append ([1,2,3], [4,5,6]):

append(xs, (y:ys)) gives us [2,3,4,5,6] – does that help?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((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?append (xs, ys) gives us [2,3,5,6] – does that help?

04/22/2304/22/23 55

Induction on Lists: “append”

Answer: use append (xs, (y:ys)) as the induction Answer: use append (xs, (y:ys)) as the induction hypothesis. Thus, there is only one parameter of hypothesis. Thus, there is only one parameter of recursion. The general case is: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))

04/22/2304/22/23 66

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

04/22/2304/22/23 77

Induction on Lists: “append”

Final solution:Final solution:

append :: ([*], [*]) -> [*]

append ([], any) = any

append ((x:xs), any) = x : (append (xs, any))

04/22/2304/22/23 88

Passing data between functions

A functional program usually contains A functional program usually contains several (many) functionsseveral (many) functions

Focus on how data passes between those Focus on how data passes between those functionsfunctions

Example: insertion sort “isort”Example: insertion sort “isort”

04/22/2304/22/23 99

Insertion Sort (specification)

Define “sorted list”Define “sorted list” An empty list is already sortedAn empty list is already sorted A singleton list is already sortedA 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, ANDx is less than all items in xs, AND xs is sortedxs is sorted

NB only lists of numbersNB only lists of numbers

04/22/2304/22/23 1010

Insertion Sort (strategy)

Start with two lists A and BStart with two lists A and B A is the input listA is the input list B is initially emptyB is initially empty One at a time, move an element from A to BOne at a time, move an element from A to B Ensure that at all times B is sortedEnsure that at all times B is sorted

We will need a function that can We will need a function that can insertinsert a number a number into a sorted list and return a sorted listinto a sorted list and return a sorted list

04/22/2304/22/23 1111

Insertion Sort (design)

The list B is an accumulatorThe list B is an accumulator So use accumulative recursionSo use accumulative recursion

Top-down approach: assume the function Top-down approach: assume the function “insert” exists and design the rest of the “insert” exists and design the rest of the program first (leap of faith!)program first (leap of faith!)

Then design “insert”Then design “insert”

04/22/2304/22/23 1212

Insertion sort (code 1)

|| comments…|| comments…

isort :: [num] -> [num]isort :: [num] -> [num]

isort any = xsort any []isort any = xsort any []

|| comments…|| comments…

xsort :: [num] -> [num] -> [num]xsort :: [num] -> [num] -> [num]

xsort [] sorted = sortedxsort [] sorted = sorted

xsort (x:xs) sorted = xsort xs (xsort (x:xs) sorted = xsort xs (insertinsert x sorted) x sorted)

04/22/2304/22/23 1313

Insertion sort (code 2)

Code for “insert”:Code for “insert”:

|| comments…|| comments…

insert :: num -> [num] -> [num]insert :: num -> [num] -> [num]

insert x [] = [x]insert x [] = [x]

insert x (y:ys) = (x:(y:ys)), if (x<y)insert x (y:ys) = (x:(y:ys)), if (x<y)

= ????= ????

04/22/2304/22/23 1414

Insertion sort (code 3)

Use induction hypothesis: assume that “insert x Use induction hypothesis: assume that “insert x ys” correctly inserts x into the list ys and produces ys” correctly inserts x into the list ys and produces the correct sorted list as a result:the correct sorted list as a result:

insert :: num -> [num] -> [num]insert :: num -> [num] -> [num]

insert x [] = [x]insert x [] = [x]

insert x (y:ys) = (x:(y:ys)), if (x<y)insert x (y:ys) = (x:(y:ys)), if (x<y)

= (y : (insert x ys)), otherwise= (y : (insert x ys)), otherwise

04/22/2304/22/23 1515

Modes of recursion: tail recursion

mylast :: [*] -> *mylast :: [*] -> *

mylast [] = error “no last item of empty list”mylast [] = error “no last item of empty list”

mylast (x:[]) = xmylast (x:[]) = x

mylast (x:xs) = mylast xsmylast (x:xs) = mylast xs

04/22/2304/22/23 1616

Modes of recursion: mutual recursion

nasty :: [char] -> [char]nasty :: [char] -> [char]nasty [] = []nasty [] = []nasty (‘(‘:rest) = nasty (‘(‘:rest) = xnastyxnasty rest restnasty (x:xs) = (x : (nasty xs))nasty (x:xs) = (x : (nasty xs))

xnasty :: [char] -> [char]xnasty :: [char] -> [char]xnasty [] = error “missing end bracket”xnasty [] = error “missing end bracket”xnasty (‘)’:rest) = xnasty (‘)’:rest) = nastynasty rest restxnasty (x:xs) = xnasty xsxnasty (x:xs) = xnasty xs

04/22/2304/22/23 1717

Removing mutual recursion

skip :: [char] -> [char]skip :: [char] -> [char]skip [] = []skip [] = []skip (‘(‘: rest) = skip (doskip rest)skip (‘(‘: rest) = skip (doskip rest)skip (x:rest) = (x : (skip rest))skip (x:rest) = (x : (skip rest))

doskip :: [char] -> [char]doskip :: [char] -> [char]doskip [] = error “missing end bracket”doskip [] = error “missing end bracket”doskip (‘)’:rest) = restdoskip (‘)’:rest) = restdoskip (x:xs) = doskip xsdoskip (x:xs) = doskip xs

04/22/2304/22/23 1818

Lazy evaluation: infinite lists

Evaluate fst (24, (37 / 0))Evaluate fst (24, (37 / 0)) Remember definition of fst:Remember definition of fst:

fst :: (*,**) -> *fst :: (*,**) -> *

fst (x,y) = xfst (x,y) = x

What does this function do? :-What does this function do? :-f x = (x : (f (x+1)))f x = (x : (f (x+1)))

04/22/2304/22/23 1919

Infinite lists (2)

Some forms of “bad” recursion may NOT Some forms of “bad” recursion may NOT create an infinite loop because they are create an infinite loop because they are evaluated ONLY AS FAR AS evaluated ONLY AS FAR AS NECESSARY:NECESSARY:f :: num -> [num]f :: num -> [num]

f x = (x : (f (x + 1))f x = (x : (f (x + 1))

main = hd (tl (f 34))main = hd (tl (f 34))

04/22/2304/22/23 2020

Infinite lists (3)

ones = (1 : ones)ones = (1 : ones)

main = hd (tl (tl ones))main = hd (tl (tl ones))

04/22/2304/22/23 2121

Summary

Structural induction: example “append”Structural induction: example “append” Passing data between functions: example Passing data between functions: example

“isort”“isort” Modes of recursion: tail recursion and Modes of recursion: tail recursion and

mutual recursionmutual recursion Removing mutual recursionRemoving mutual recursion Lazy evaluation: infinite listsLazy evaluation: infinite lists

top related