@@ -3,18 +3,19 @@ module Lazy.Stream ( head, tail
3 , map, apply, zip, zipWith, scanl
3 , map, apply, zip, zipWith, scanl
4 , take, drop, splitAt
4 , take, drop, splitAt
6+ , filter, takeWhile, dropWhile, splitWith
8−{-| Library for Infinite Streams
9+{-| This library is for creating and manipulating infinite streams
11−@docs cons, cons', iterate, repeat, cycle
12+@docs cons, cons', repeat, cycle, iterate
14−@docs head, tail, sampleOn, take, drop, splitAt
15+@docs head, tail, sampleOn, take, takeWhile, drop, dropWhile, splitAt, splitWith
16# Transform
17# Transform
17−@docs map, apply, zip, zipWith, scanl
18+@docs map, zip, zipWith, scanl, filter, apply
@@ -27,88 +28,170 @@ data Stream a = S (Lazy (a, Stream a))
27unS : Stream a -> (a, Stream a)
28unS : Stream a -> (a, Stream a)
28unS (S t) = force t
29unS (S t) = force t
30−{-| Compute the first element of a Stream -}
31+{-| Get the first element of a stream, called the `head`.
31head : Stream a -> a
37head : Stream a -> a
32head = fst . unS
38head = fst . unS
34−{-| Compute the next piece of a Stream -}
40+{-| Drop the `head` of a stream, leaving you with the `tail`.
35tail : Stream a -> Stream a
47tail : Stream a -> Stream a
36tail = snd . unS
48tail = snd . unS
38−{-| Create a Stream -}
50+{-| Create a stream:
54+ones = cons 1 (\() -> ones)
39cons : a -> (() -> Stream a) -> Stream a
57cons : a -> (() -> Stream a) -> Stream a
40cons x txs = let mtxs = lazy txs in
58cons x txs = let mtxs = lazy txs in
41 S . lazy <| \() ->
59 S . lazy <| \() ->
42 (x, force mtxs)
60 (x, force mtxs)
44−{-| Lazily create a Stream. -}
62+{-| Create a stream that is slightly more lazy. Notice that the
63+head of the stream is defined within the thunk, so its evaluation
64+is delayed. This is nice when each element of the stream is costly to compute.
68+ones = cons' (\_ -> (1,ones))
45cons' : (() -> (a, Stream a)) -> Stream a
71cons' : (() -> (a, Stream a)) -> Stream a
46cons' = S . lazy
72cons' = S . lazy
48−{-| Create a stream of repeated applications of f to x:
74+{-| Iteratively apply a function to a value:
77+-- x, f x, f (f x), f (f (f x)), ...
50− iterate f x = S.cons x (S.cons (f x) (S.cons (f (f x)) ...))
80+-- 2, 4, 8, 16, ...
81+powersOf2 = iterate (\n -> n^2) 2
52iterate : (a -> a) -> a -> Stream a
84iterate : (a -> a) -> a -> Stream a
53−iterate f x = cons' <| \() ->
85+iterate f x =
54− (x, iterate f (f x))
86+ cons' <| \_ -> (x, iterate f (f x))
88+{-| Repeat a value infinitely:
56−{-| Create an infinite Stream of xs. -}
90+```haskell
57repeat : a -> Stream a
95repeat : a -> Stream a
58repeat x = let go = cons x <| \() -> go
96repeat x = let go = cons x <| \() -> go
61−{-| Cycle through the elements of the nonempty list (x :: xs) -}
99+{-| Infinitely cycle through a list, where the head and tail of
100+the list are given separately to ensure that no one tries to cycle
104+-- "Alice", "Bob", "Alice", "Bob", ...
105+cycle "Alice" ["Bob"]
62cycle : a -> [a] -> Stream a
108cycle : a -> [a] -> Stream a
63−cycle x xs = let cycle' ys = case ys of
110+ let cycle' ys = case ys of
64− [] -> go
111+ [] -> go
65− (y :: ys) -> cons y <| \() ->
112+ (y :: ys) -> cons y (\_ -> cycle' ys)
68− (x, cycle' xs)
113+ go = cons' <| \_ -> (x, cycle' xs)
71−{-| Apply a function to every element of a Stream. -}
116+{-| Apply a function to every element of a Stream.
120+twos = map (\n -> n + 1) ones
72map : (a -> b) -> Stream a -> Stream b
123map : (a -> b) -> Stream a -> Stream b
73−map f xs = cons' <| \() ->
124+map f xs =
74− (f (head xs), map f (tail xs))
125+ cons' <| \_ -> (f (head xs), map f (tail xs))
76−{-| Pairwise apply a stream of functions to a stream of inputs.
127+{-| Pairwise apply a stream of functions to a stream of arguments.
77− Together with map, generalizes zipWith to n arguments.
128+When paired with `map`, this can be used to emulate `zipWith` over *n* streams.
79− zipWith2 : (a -> b -> c -> d) -> Stream a -> Stream b -> Stream c -> Stream d
131+zipWith3 : (a -> b -> c -> d) -> Stream a -> Stream b -> Stream c -> Stream d
80− zipWith2 f xs ys zs = f `S.map` xs `S.apply` ys `S.apply` zs
132+zipWith3 f xs ys zs = f `S.map` xs `S.apply` ys `S.apply` zs
82apply : Stream (a -> b) -> Stream a -> Stream b
135apply : Stream (a -> b) -> Stream a -> Stream b
83apply fs xs = zipWith (<|) fs xs
136apply fs xs = zipWith (<|) fs xs
85−{-| Combine two streams, combining them into tuples pairwise. -}
138+{-| Combine two streams, putting them into tuples pairwise:
141+-- (1,2), (1,4), (1,8), (1,16), ...
142+pairs = zip ones powersOf2
86−zip : Stream a -> Stream b -> Stream (a, b)
145+zip : Stream a -> Stream b -> Stream (a,b)
87zip = zipWith (\x y -> (x,y))
146zip = zipWith (\x y -> (x,y))
89−{-| Combine two streams, combining them with the given function. -}
148+{-| Combine two streams, applying the given function pairwise:
152+zipWith (+) ones powersOf2
90zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
155zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
91zipWith f xs ys = cons' <| \() ->
156zipWith f xs ys = cons' <| \() ->
92 (f (head xs) (head ys),
157 (f (head xs) (head ys),
93 zipWith f (tail xs) (tail ys))
158 zipWith f (tail xs) (tail ys))
95−{-| Reduce a Stream from the left, building an infinite stream of reductions. -}
160+{-| Scan over a stream from the left, building an infinite stream of reductions.
164+runningTotal = scanl (+) 0 ones
96scanl : (a -> b -> b) -> b -> Stream a -> Stream b
167scanl : (a -> b -> b) -> b -> Stream a -> Stream b
97−scanl f init xs = cons' <| \() ->
168+scanl f init xs =
99− scanl f (f (head xs) init) (tail xs))
169+ cons' <| \() -> (init, scanl f (f (head xs) init) (tail xs))
101−{-| Compute the first n elements of a stream into a list. -}
171+{-| Take the first *n* elements of a stream
174+take 5 powersOf2 == [2,4,8,16,32]
102take : Int -> Stream a -> [a]
177take : Int -> Stream a -> [a]
103take n xs = fst <| splitAt n xs
178take n xs = fst <| splitAt n xs
105−{-| Drop n elements from the front of a stream. -}
180+{-| Drop the first *n* elements of a stream
183+-- 64, 128, 256, 512, ...
106drop : Int -> Stream a -> Stream a
187drop : Int -> Stream a -> Stream a
107drop n xs = snd <| splitAt n xs
188drop n xs = snd <| splitAt n xs
109−{-| Combination of take and drop.
190+{-| Combination of `take` and `drop`
111− splitAt n xs == (take n xs, drop n xs)
193+splitAt n xs == (take n xs, drop n xs)
113splitAt : Int -> Stream a -> ([a], Stream a)
196splitAt : Int -> Stream a -> ([a], Stream a)
114splitAt n xs = case n of
197splitAt n xs = case n of
@@ -117,9 +200,76 @@ splitAt n xs = case n of
117 in (head xs :: heads, end)
200 in (head xs :: heads, end)
119{-| Turn a stream into a signal of the elements of the stream,
202{-| Turn a stream into a signal of the elements of the stream,
120− advancing through the stream whenever an event in the given signal is
203+advancing through the stream whenever an event in the given signal is
123sampleOn : Signal b -> Stream a -> Signal a
206sampleOn : Signal b -> Stream a -> Signal a
124sampleOn sig str = let tails = foldp (\_ -> tail) str sig in
207sampleOn sig str = let tails = foldp (\_ -> tail) str sig in
125 head <~ tails
208 head <~ tails
210+{-| Filter the elements of a Stream according to a predicate.
214+filter isOdd naturals
216+-- Bad! Infinite loop!
220+This can infinite loop if no more elements in the stream satisfy the predicate!
222+filter : (a -> Bool) -> Stream a -> Stream a
223+filter pred xs = cons' <| (\() ->
224+ let (hd, tl) = unS xs in
226+ True -> (hd, filter pred tl)
227+ False -> unS <| filter pred tl)
229+{-| Take values from the stream for as long as the predicate holds.
230+This can infinite loop if all elements of the stream satisfy the predicate!
233+takeWhile (\n -> n < 10) powersOf2 == [2,4,8]
235+-- Bad! Infinite loop!
236+takeWhile isEven powersOf2
239+This can infinite loop if all elements of the stream satisfy the predicate!
241+takeWhile : (a -> Bool) -> Stream a -> [a]
242+takeWhile pred xs = fst <| splitWith pred xs
244+{-| Drop values from the stream as long as the predicate holds.
247+-- 16, 32, 64, 128, ...
248+dropWhile (\n -> n < 10) powersOf2
250+-- Bad! Infinite loop!
251+dropWhile isEven powersOf2
254+This can infinite loop if all elements of the stream satisfy the predicate!
256+dropWhile : (a -> Bool) -> Stream a -> Stream a
257+dropWhile pred xs = snd <| splitWith pred xs
259+{-| Combination of `takeWhile` and `dropWhile`. Split a stream when
260+the predicate no longer holds.
263+splitWith pred xs == (takeWhile pred xs, dropWhile pred xs)
265+splitWith (\n -> n < 10) powersOf2 == ([2,4,8], ...)
268+This can infinite loop if all elements satisfy the predicate!
270+splitWith : (a -> Bool) -> Stream a -> ([a], Stream a)
271+splitWith pred xs = let (hd, tl) = unS xs in
273+ True -> let (taken, dropped) = splitWith pred tl
274+ in (hd :: taken, dropped)