Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS321 Functional Programming 2 © JAS 2005 2-1 Programming with Streams A stream is never finite and could be defined as special polymorphic type data stream.

Similar presentations


Presentation on theme: "CS321 Functional Programming 2 © JAS 2005 2-1 Programming with Streams A stream is never finite and could be defined as special polymorphic type data stream."— Presentation transcript:

1 CS321 Functional Programming 2 © JAS 2005 2-1 Programming with Streams A stream is never finite and could be defined as special polymorphic type data stream a = a :^ Stream a but it is more convenient to “simulate” them with standard lists, but never use the empty list [] inf = 1 : inf-- the infinite list of 1's from n = n : from (n+1) nats = from 0-- the natural numbers

2 CS321 Functional Programming 2 © JAS 2005 2-2 series f a = a : series f (f a) -- a general series generating function -- actually defined in the prelude as -- iterate nats2 = series (+1) 0 inf2 = series (\i -> i) 1 powers n = series (* n) 1-- the powers of n These definitions work because of Haskell’s Normal Order Reduction / Lazy Evaluation Strategy

3 CS321 Functional Programming 2 © JAS 2005 2-3 Another useful operation is to find the limit of a stream or list (what value does it tend to?) limit crit hs@(h:t) | crit hs= h | otherwise = limit crit t -- crit is a function which -- determines whether the first two -- elements of a list are similar -- enough epsilon (h:(j:js)) = (h-j) < 0.000001

4 CS321 Functional Programming 2 © JAS 2005 2-4 A classic example of a stream computation is to generate prime numbers remove p = filter (not. p) primes = sieve [2..] sieve (p:nos) = p:sieve (remove (multsof p) nos) where multsof p n = n 'rem' p == 0

5 CS321 Functional Programming 2 © JAS 2005 2-5 Stream problems and interconnected processes A classic problem (attributed to Hamming) is to generate in ascending order the sequence of positive numbers divisible only by 2, 3 and 5. ie the stream of nos 2 m 3 n 5 p where m=0.., n=0.., p=0.. An alternative way of expressing this (due to Dijkstra) is the value 1 is in the sequence if x is in the sequence then so is 2x, 3x, 5x no other items are in the sequence

6 CS321 Functional Programming 2 © JAS 2005 2-6 It is fairly easy to define functions which given a sequence generate sequences multiplied by 2, 3 or 5 t2 (h:t) = 2*h : t2 t t3 (h:t) = 3*h : t3 t t5 (h:t) = 5*h : t5 t or times n (h:t) = n*h : times n t The problem now is to merge the streams in ascending order and remove duplicates

7 CS321 Functional Programming 2 © JAS 2005 2-7 t2 t3 t5 merge : [5,10,15,20..] [3,6,9,12..] [2,4,6,8..] [1,2,3,4..] 1

8 CS321 Functional Programming 2 © JAS 2005 2-8 We define a merge function merge x@(hx:tx) y@(hy:ty) | hx < hy= hx : merge tx y | hx == hy= merge tx y | otherwise= hy : merge x ty and a complete solution is h = 1:h235 h2 = times 2 h h3 = times 3 h h5 = times 5 h h23 = merge h2 h3 h235 = merge h23 h5

9 CS321 Functional Programming 2 © JAS 2005 2-9 Sets and Infinite Streams To remove duplicates from a finite list (to make it represent a set) we can define the following function. nub [] = [] nub (h:t)| elem h t= nub t | otherwise = h : nub t On an infinite list the test elem h t would never terminate.

10 CS321 Functional Programming 2 © JAS 2005 2-10 nub = rm [] where rm sofar []= [] rm sofar (h:t) | elem h sofar = rm sofar t | otherwise = h:rm (h:sofar) t sofar is a list of elements found so far – as the list/set grows this will grow leading to what is sometimes termed a “space leak” nub [] = [] nub (x:xs) = x: nub (filter (/= x) xs With this version a series of nested calls to a filter function will build up – again causing potential space/efficiency problem. Such problems are a hidden danger in languages using lazy evaluation.

11 CS321 Functional Programming 2 © JAS 2005 2-11 Recall the concept of list comprehensions [expr | qualifiers] To define prime numbers we could write primes = sieve [2..] sieve (prime : rest) = prime : sieve [r|r<-rest,r 'rem' prime/=0] This would appear to require the implementation of an infinite set, with the inherent problems of space leaks if we try and remove duplicates. Hence an implementation may well ignore the existence of duplicate elements.

12 CS321 Functional Programming 2 © JAS 2005 2-12 Consider a case with more than one list cart s t = [ (x,y) | x <-s, y<-t] This produces the cartesian product of two sets s and t. If s and t are the natural numbers how can we guarantee that we produce all pairs eventually? (This is known as fairness) If we iterate over s first we would never get beyond pairs of the form (n,1). The solution is for the programmer (or the system, though this is not always satisfactory) to define a different generation order - diagonalisation. Eg intpairs=[(x,n-x)|n<-[0..],x<-[0..n]]

13 CS321 Functional Programming 2 © JAS 2005 2-13 A recursive stream example fib :: Integer -> Integer fib 0 = 1 fib 1 = 1 fib n = fib (n-1) + fib (n-2) fib 8  fib 7 + fib 6  (fib 6 + fib 5) + (fib 5 + fib 4)  ((fib 5 + fib 4) + (fib 4 + fib 3)) + ((fib 4 + fib 3) + (fib 3 + fib 2)) ………………

14 CS321 Functional Programming 2 © JAS 2005 2-14 Fibonacci seq 1 1 2 3 5 8 13 21 tail of Fibonnaci seq 1 2 3 5 8 13 21 34 tail of tail of fib seq 2 3 5 8 13 21 34 55 fibs :: [integer] fibs = 1 : 1 : zipWith (+) fibs (tail fibs) fibs  (1:1: zW (+) fibs (tail fibs))  (1:1: zW (+) (1:1:zW+ fibs (tail fibs)) (1:zW+ fibs (tail fibs)) tf

15 CS321 Functional Programming 2 © JAS 2005 2-15 zipWith (+) (:) 1 1

16 CS321 Functional Programming 2 © JAS 2005 2-16 Client Servers using Streams client :: [Response] -> [Request] server :: [Request] -> [Response] reqs = client resps resps = server reqs type Request = Integer type Response = Integer client ys = 1 : ys server xs = map (+1) xs

17 CS321 Functional Programming 2 © JAS 2005 2-17 1 (:) (+1) server client reqs = 1,2,3.. resps = 2,3,4.. reqs  client resps  1:resps  1:server reqs  1:tr where tr = server reqs  1:tr where tr = 2:server tr  1:tr where tr = 2:tr2 where tr2 = server tr  1:tr where tr = 2:tr2 where tr2 = 3:server tr2  1:2:tr2 where tr2 = 3:server tr2

18 CS321 Functional Programming 2 © JAS 2005 2-18 client (y:ys) = if ok y then 1:(y:ys) else error “faulty server” ok y = True reqs  client resps  client (server reqs)  client (server (client resps))  ………

19 CS321 Functional Programming 2 © JAS 2005 2-19 client ys = 1 : if ok (head ys) then ys else error “faulty server” client ~(y:ys) = 1:if ok y then(y:ys) else error “faulty server” reqs  client resps  1:if ok y then y:ys else error “fault..” where y:ys = resps  1:(y:ys) where y:ys = resps  1:resps

20 CS321 Functional Programming 2 © JAS 2005 2-20 Memoization fibsFn :: () -> [Integer] fibsFn x = 1:1:zipWith(+) (fibsFn()) (tail (fibsFn())) fibsFn ()  1:1:zW+ (fibsFn()) (tail (fibsFn()))  1:tf where tf = 1:zW+(fibsFn())(tail( )) fibsFn() Equal? – no general way to tell

21 CS321 Functional Programming 2 © JAS 2005 2-21 Imagine a function memo :: (a->b)->(a->b) Which is such that memo f x = f x And records values f has been applied to and the result (the memo) Assume a function memo1 which saves just one argument and result mfibsFn :: () -> [Integer] mfibsFn x = let mfibs = memo1 mfibsFn in 1:1:zipWith(+)(mfibs())(tail(mfibs()))

22


Download ppt "CS321 Functional Programming 2 © JAS 2005 2-1 Programming with Streams A stream is never finite and could be defined as special polymorphic type data stream."

Similar presentations


Ads by Google