Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 14 Programming With Streams. Streams  A stream is an infinite sequence of values.  We could define a special data type for them: data Stream.

Similar presentations


Presentation on theme: "Chapter 14 Programming With Streams. Streams  A stream is an infinite sequence of values.  We could define a special data type for them: data Stream."— Presentation transcript:

1 Chapter 14 Programming With Streams

2 Streams  A stream is an infinite sequence of values.  We could define a special data type for them: data Stream a = a :^ Stream a but in practice it’s easier to use conventional lists, ignoring [], so that we can reuse the many operations on lists.  Streams are often defined recursively, such as: twos = 2 : twos  By calculation: twos  2 : twos  2 : 2 : twos  2 : 2 : 2 : twos  …  This calculation does not terminate – yet it is not the same as _|_, in that it yields useful information.  [ Another example: numsfrom n = n : numsfrom (n+1) ]

3 Lazy Evaluation  Two ways to calculate “head twos”: head twoshead twos  head (2 : twos)  head (2 : twos)  2  head (2 : 2 : twos)  head (2 : 2 : 2 : twos)  …  One strategy terminates, the other doesn’t.  Normal order calculation guarantees finding a terminating sequence if one exists.  Normal order calculation: always choose the outermost calculation (e.g.: unfolding “head” above instead of unfolding “twos”).  Also called lazy evaluation, or non-strict evaluation.  (In contrast to eager or strict evaluation.)

4 Example: Fibonacci Sequence  Well-known sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …  Here is a Haskell program that mimics the mathematical definition: fib 0= 1 fib 1= 1 fib n = fib (n-1) + fib (n-2)  Unfortunately, this program is terribly inefficient (perform the calculation to see this). Indeed, it has an exponential blow-up.  Perhaps surprisingly, it is more efficient to create the infinite stream of Fibonacci numbers first, then select to the one we need.

5 Fibs, cont’d  Note this relationship: fibs1 1 2 3 5 8 13 21 34 +tail fibs1 2 3 5 8 13 21 34 55 --------------------------------------------------------- tail (tail fibs)2 3 5 8 13 21 34 55 89  This is easily transcribed into Haskell: fibs = 1 : 1 : add fibs (tail fibs) where add = zipWith (+)  And then finally: fib n = fibs !! n tail (tail fibs)

6 Chasing One’s Tail  Notice in: fibs  1 : 1 : add fibs (tail fibs) that “tail fibs” starts right here.  Introduce a name for that value so it can be shared: fibs  1 : tf where tf = 1 : add fibs (tail fibs)  1 : tf where tf = 1 : add fibs tf  Doing this again for the tail of the tail yields:  1 : tf where tf = 1 : tf2 where tf2 = add fibs tf  Finally, unfold add:  1 : tf where tf = 1 : tf2 where tf2 = 2 : add tf tf2

7 Garbage Collection  Because of sharing, exponential blowup is avoided.  In a few more steps we have: fibs  1 : tf where tf = 1 : tf2 where tf2 = 2 : tf3 where tf3 = 3 : add tf2 tf3  Now note that “tf” is only used in one place, and thus might as well be eliminated, yielding:  1 : 1 : tf2 where tf2 = 2 : tf3 where tf3 = 3 : add tf2 tf3  Think of this as “garbage collection” of names.

8 Stream Diagrams  An alternative (perhaps better) way to depict sharing is graphically using a stream diagram.  Another example: client-server interactions. 1 1 fibs 1,1,2,3,5,8,… 1,2,3,5,8,… 2,3,5,8,… (:) add

9 Inductive Properties of Streams  Consider these properties of lists: take n xs ++ drop n xs = xs reverse (reverse xs) = xs  Are they true for streams, i.e. if “xs” is infinite?  The first one, yes, the second one, no (why?).  To prove general properties on streams, we use induction, but now the base case is _|_, not [].  To see why this works, think of _|_ as an approximation to a value (it happens to be the least approximation, containing no information at all).

10 Bottom as an Approximation  For example, here are increasingly more accurate approximations to [1,2,3], culminating in the list itself: _|_-- no information at all 1 : _|_-- one element, then no information 1 : 2 : _|_-- two elements, then no information 1 : 2 : 3 : _|_-- three elements, then no information 1 : 2 : 3 : [ ]-- three elements, then [ ].  In the case of an infinite list, we have: _|_-- note every list 1 : _|_-- ends in _|_ 1 : 2 : _|_ 1 : 2 : 3 : _|_ 1 : 2 : 3 : 4 : _|_ 1 : 2 : 3 : 4 : 5 : _|_...  The limit of a sequence of partial lists is an infinite list. Definition: A list ending in _|_ is called a partial list.

11 Induction on Streams  Key point: If a property P (expressed as an equation in Haskell) is true for every partial list in a sequence whose limit is the stream xs, then P is also true of xs.  To prove that it is true of the sequence of partial lists, we use induction: First prove that P(_|_) holds. Then assume that P(xs) holds, and prove that P(x:xs) holds.  Note the constraint on P: “expressed as an equation in Haskell”. This excludes non-continuous properties such as “xs is partial”, which, although trivially true of every partial list, is not true of an infinite list.

12 Example 1  Theorem: For all lists xs: take n xs ++ drop n xs = xs  The base case for xs = [ ], and the induction step, are easy to prove. This establishes the validity of the theorem for finite lists.  For infinite lists, we first note that the property is stated as an equation in Haskell.  Then we prove the base case xs = _|_: n>0:n=0: take n _|_ ++ drop n _|_  take 0 _|_ ++ drop 0 _|_  _|_ ++ drop n _|_  [ ] ++ drop 0 _|_  _|_  drop 0 _|_  _|_

13 Example 2  Theorem: For all lists xs: reverse (reverse xs) = xs  True for finite lists: the base case xs = [ ] is easy, and so is the induction step, relying on the lemma: reverse (xs ++ ys) = reverse ys ++ reverse xs  For infinite lists, the base case xs = _|_ also holds! reverse (reverse _|_)  reverse _|_  _|_  What went wrong? Answer: the lemma does not hold for partial lists! In particular, the base case fails: reverse (_|_ ++ ys)reverse ys ++ reverse _|_  reverse _|_  reverse ys ++ _|_  _|_


Download ppt "Chapter 14 Programming With Streams. Streams  A stream is an infinite sequence of values.  We could define a special data type for them: data Stream."

Similar presentations


Ads by Google