Presentation is loading. Please wait.

Presentation is loading. Please wait.

Cse536 Functional Programming Lecture #14, Nov. 10, 2004 Programming with Streams –Infinite lists v.s. Streams –Normal order evaluation –Recursive streams.

Similar presentations


Presentation on theme: "Cse536 Functional Programming Lecture #14, Nov. 10, 2004 Programming with Streams –Infinite lists v.s. Streams –Normal order evaluation –Recursive streams."— Presentation transcript:

1 Cse536 Functional Programming Lecture #14, Nov. 10, 2004 Programming with Streams –Infinite lists v.s. Streams –Normal order evaluation –Recursive streams –Stream Diagrams –Lazy patterns –memoization –Inductive properties of infinite lists Reading assignment –Chapter 14. Programming with Streams –Chapter 15. A module of reactive animations

2 Cse536 Functional Programming Infinite lists v.s. Streams data Stream a = a :^ Stream a A stream is an infinite list. It is never empty We could define a stream in Haskell as written above. But we prefer to use lists. This way we get to reuse all the polymorphic functions on lists.

3 Cse536 Functional Programming Infinite lists and bottom twos = 2 : twos twos = 2 : (2 : twos) twos = 2 : (2 : (2 : twos)) twos = 2 : (2 : (2 : (2 : twos))) bot :: a bot = bot What is the difference between twos and bot ? Sometimes we write z for bot

4 Cse536 Functional Programming Normal Order evaluation Why does head(twos) work? –Head (2 : twos) –Head(2 : (2 : twos)) –Head (2: (2 : (2 : twos))) The outermost – leftmost rule. Outermost –Use the body of the function before its arguments Leftmost –Use leftmost terms: (K 4) (5 + 2) –Be careful with Infix: (m + 2) `get` (x:xs)

5 Cse536 Functional Programming Normal order continued Let let x = y + 2 z = x / 0 in if x=0 then z else w Where f w = if x=0 then z else w where x = y + 2 z = x / 0 Case exp’s –case f x of [] -> a ; (y:ys) -> b

6 Cse536 Functional Programming Recursive streams fibA 0 = 1 fibA 1 = 1 fibA n = fibA(n-1) + fibA(n-2) Unfold this a few times fibA 8 = fibA 7 + fibA 6 = (fibA 6 + fibA 5) + (fibA 5 + fibA 4) = ((fibA 5 + fibA 4) + (fibA 4 + fibA 3)) +((fibA 4 + fibA 3) + (fibA 3 + fibA 2))

7 Cse536 Functional Programming Fibonacci Stream fibs :: [ Integer ] fibs = 1 : 1 : (zipWith (+) fibs (tail fibs)) This is much faster! And uses less resources. Why? 1 1 2 3 5 8 13 21 … fibonacci sequence + 1 2 3 5 8 13 21 34 … tail of fibonacci sequence 2 3 5 8 13 21 34 55 … tail of tail of fibonacci sequence

8 Cse536 Functional Programming Abstract on tail of fibs fibs = 1 : 1 : (add fibs (tail fibs)) = 1 : tf where tf = 1 : add fibs (tail fibs) = 1 : tf where tf = 1 : add fibs tf Abstract on tail of tf = 1 : tf where tf = 1 : tf2 tf2 = add fibs tf Unfold add = 1 : tf where tf = 1 : tf2 tf2 = 2 : add tf tf2 Add x y = zipWith (+) x y

9 Cse536 Functional Programming Abstract and unfold again fibs = 1 : tf where tf = 1 : tf2 tf2 = 2 : add tf tf2 = 1 : tf where tf = 1 : tf2 tf2 = 2 : tf3 tf3 = add tf tf2 = 1 : tf where tf = 1 : tf2 tf2 = 2 : tf3 tf3 = 3 : add tf2 tf3 tf is used only once, so eliminate = 1 : 1 : tf2 where tf2 = 2 : tf3 tf3 = 3 : add tf2 tf3

10 Cse536 Functional Programming Again This can go on forever. But note how the sharing makes the inefficiencies of fibA go away. fibs = 1 : 1 : 2 : tf3 where tf3 = 3 : tf4 tf4 = 5 : add tf3 tf4 fibs = 1 : 1 : 2 : 3 : tf4 where tf4 = 5 : tf5 tf5 = 8 : add tf4 tf5

11 Cse536 Functional Programming Stream Diagrams (:) add fibs = [1,1,2,3,5,8,…] [1,2,3,5,8, …] 1 1 [2,3,5,8,…] Streams are “wires” along which values flow. Boxes and circles take wires as input and produce values for new wires as output. Forks in a wire send their values to both destinations A stream diagram corresponds to a Haskell function (usually recursive)

12 Cse536 Functional Programming Example Stream Diagram counter :: [ Bool ] -> [ Int ] counter inp = out where out = if* inp then* 0 else* next next = [0] followedBy map (+ 1) out [0] if* 0 inp out +1 next

13 Cse536 Functional Programming Example counter :: [ Bool ] -> [ Int ] counter inp = out where out = if* inp then* 0 else* next next = [0] followedBy map (+ 1) out [0] if* 0 F... 0... +1 0... 1... out next

14 Cse536 Functional Programming Example counter :: [ Bool ] -> [ Int ] counter inp = out where out = if* inp then* 0 else* next next = [0] followedBy map (+ 1) out [0] if* 0 F:F.. 0:1.. +1 0:1.. 1:2.. out next

15 Cse536 Functional Programming Example counter :: [ Bool ] -> [ Int ] counter inp = out where out = if* inp then* 0 else* next next = [0] followedBy map (+ 1) out [0] if* 0 F:F:T.. 0:1:0.. +1 0:1:2 1:2:1.. out next

16 Cse536 Functional Programming Client, Server Example type Response = Integer type Request = Integer client :: [Response] -> [Request] client ys = 1 : ys server :: [Request] -> [Response] server xs = map (+1) xs reqs = client resps resps = server reqs Typical. A set of mutually recursive equations

17 Cse536 Functional Programming reqs = client resps = 1 : resps = 1 : server reqs Abstract on (tail reqs) = 1 : tr where tr = server reqs Use definition of server = 1 : tr where tr = 2 : server reqs abstract = 1 : tr where tr = 2 : tr2 tr2 = server reqs Since tr is used only once = 1 : 2 : tr2 where tr2 = server reqs Repeat as required client ys = 1 : ys server xs = map (+1) xs reqs = client resps resps = server reqs

18 Cse536 Functional Programming Lazy Patterns Suppose client wants to test servers responses. clientB (y : ys) = if ok y then 1 :(y:ys) else error "faulty server" where ok x = True server xs = map (+1) xs Now what happens... Reqs = client resps = client(server reqs) = client(server(client resps)) = client(server(client(server reqs)) We can’t unfold

19 Cse536 Functional Programming Solution 1 Rewrite client client ys = 1 : (if ok (head ys) then ys else error "faulty server") where ok x = True Pulling the (:) out of the if makes client immediately exhibit a cons cell Using (head ys) rather than the pattern (y:ys) makes the evaluation of ys lazy

20 Cse536 Functional Programming Solution 2 – lazy patterns client ~(y:ys) = 1 : (if ok y then y:ys else err) where ok x = True err = error "faulty server” Calculate using where clauses Reqs = client resps = 1 : (if ok y then y:ys else err) where (y:ys) = resps = 1 : y : ys where (y:ys) = resps = 1 : resps In Haskell the ~ before a pattern makes it lazy

21 Cse536 Functional Programming Memoization fibsFn :: () -> [ Integer ] fibsFn () = 1 : 1 : (zipWith (+) (fibsFn ()) (tail (fibsFn ()))) Unfolding we get: fibsFn () = 1:1: add (fibsFn()) (tail (fibsFn ())) = 1 : tf where tf = 1:add(fibsFn())(tail(fibsFn())) But we can’t proceed since we can’t identify tf with tail(fibsFn()). Further unfolding becomes exponential.

22 Cse536 Functional Programming memo1 We need a function that builds a table of previous calls. Memo : (a -> b) -> (a -> b) 11 22 33 10 45 Memo fib x = if x in_Table_at i then Table[i] else set_table(x,fib x); return fib x Memo1 builds a table with exactly 1 entry.

23 Cse536 Functional Programming Using memo1 mfibsFn x = let mfibs = memo1 mfibsFn in 1:1:zipWith(+)(mfibs())(tail(mfibs())) Main> take 20 (mfibsFn()) [1,1,2,3,5,8,13,21,34,55,89,144,233,377, 610,987,1597,2584,4181,6765]

24 Cse536 Functional Programming Inductive properties of infinite lists Which properties are true of infinite lists –take n xs ++ drop n xs = xs –reverse(reverse xs) = xs Recall that z is the error or non-terminating computation. Think of z as an approximation to an answer. We can get more precise approximations by: ones = 1 : ones z 1 : z 1 : 1 : z 1 : 1 : 1 : z

25 Cse536 Functional Programming Proof by induction To do a proof about infinite lists, do a proof by induction where the base case is z, rather than [] since an infinite list does not have a [] case (because its infinite). –1) Prove P{ z } –2) Assume P{xs} is true then prove P{x:xs} Auxiliary rule: –Pattern match against z returns z. I.e. c ase z of { [] -> e; y:ys -> f }

26 Cse536 Functional Programming Example Prove: P{ x } == (x ++ y) ++ w = x ++ (y++w) 1)Prove P{ z } ( z ++ y) ++ w = z ++ (y++w) 2)Assume P{xs} (xs ++ y) ++ w = xs ++ (y++w) Prove P{x:xs} (x:xs ++ y) ++ w = x:xs ++ (y++w)

27 Cse536 Functional Programming Base Case ( z ++ y) ++ w = z ++ (y++w) ( z ++ y) ++ w pattern match in def of ++ z ++ w pattern match in def of ++ z pattern match in def of ++ z ++ (y++w)

28 Cse536 Functional Programming Induction step 1)Assume P{xs} (xs ++ y) ++ w = xs ++ (y++w) Prove P{x:xs} (x:xs ++ y) ++ w = x:xs ++ (y++w) (x:xs ++ y) ++ w Def of (++) (x:(xs ++ y)) ++ w Def of (++) x :((xs ++ y) ++ w) Induction hypothesis x : (xs ++ (y ++ w)) Def of (++) (x:xs) ++ (y ++ w)


Download ppt "Cse536 Functional Programming Lecture #14, Nov. 10, 2004 Programming with Streams –Infinite lists v.s. Streams –Normal order evaluation –Recursive streams."

Similar presentations


Ads by Google