@@ -7,12 +7,12 @@ module Lazy.Stream ( head, tail
77
88{-| Library for Infinite Streams
99
10+# Create
11+@docs cons, cons', iterate, repeat, cycle
12+
1013# Observe
1114@docs head, tail, sampleOn, take, drop, splitAt
1215
13−# Create
14−@docs cons', iterate, repeat, cycle
15−
1616# Transform
1717@docs map, apply, zip, zipWith, scanl
1818
@@ -27,65 +27,95 @@ data Stream a = S (Lazy (a, Stream a))
2727unS : Stream a -> (a, Stream a)
2828unS (S t) = force t
2929
30+{-| Compute the first element of a Stream -}
3031head : Stream a -> a
3132head = fst . unS
3233
34+{-| Compute the next piece of a Stream -}
3335tail : Stream a -> Stream a
3436tail = snd . unS
3537
38+{-| Create a Stream -}
3639cons : a -> (() -> Stream a) -> Stream a
3740cons x txs = let mtxs = lazy txs in
3841 S . lazy <| \() ->
3942 (x, force mtxs)
4043
44+{-| Lazily create a Stream. -}
4145cons' : (() -> (a, Stream a)) -> Stream a
4246cons' = S . lazy
4347
48+{-| Create a stream of repeated applications of f to x:
49+
50+ iterate f x = S.cons x (S.cons (f x) (S.cons (f (f x)) ...))
51+-}
4452iterate : (a -> a) -> a -> Stream a
4553iterate f x = cons' <| \() ->
4654 (x, map f (iterate f x))
4755
56+{-| Create an infinite Stream of xs. -}
4857repeat : a -> Stream a
4958repeat x = iterate id x
50−
59+
60+{-| Cycle through the elements of the nonempty list (x :: xs) -}
5161cycle : a -> [a] -> Stream a
5262cycle x xs = let cycle' ys = case ys of
5363 [] -> cons' <| \() ->
5464 (x, cycle' xs)
5565 in cycle' []
5666
67+{-| Apply a function to every element of a Stream. -}
5768map : (a -> b) -> Stream a -> Stream b
5869map f xs = cons' <| \() ->
5970 (f (head xs), map f (tail xs))
6071
72+{-| Pairwise apply a stream of functions to a stream of inputs.
73+ Together with map, generalizes zipWith to n arguments.
74+
75+ zipWith2 : (a -> b -> c -> d) -> Stream a -> Stream b -> Stream c -> Stream d
76+ zipWith2 f xs ys zs = f `S.map` xs `S.apply` ys `S.apply` zs
77+-}
6178apply : Stream (a -> b) -> Stream a -> Stream b
6279apply fs xs = zipWith (<|) fs xs
63−
80+
81+{-| Combine two streams, combining them into tuples pairwise. -}
6482zip : Stream a -> Stream b -> Stream (a, b)
6583zip = zipWith (\x y -> (x,y))
6684
85+{-| Combine two streams, combining them with the given function. -}
6786zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
6887zipWith f xs ys = cons' <| \() ->
6988 (f (head xs) (head ys),
7089 zipWith f (tail xs) (tail ys))
7190
91+{-| Reduce a Stream from the left, building an infinite stream of reductions. -}
7292scanl : (a -> b -> b) -> b -> Stream a -> Stream b
7393scanl f init xs = cons' <| \() ->
7494 (init,
7595 scanl f (f (head xs) init) (tail xs))
7696
97+{-| Compute the first n elements of a stream into a list. -}
7798take : Int -> Stream a -> [a]
7899take n xs = fst <| splitAt n xs
79100
101+{-| Drop n elements from the front of a stream. -}
80102drop : Int -> Stream a -> Stream a
81103drop n xs = snd <| splitAt n xs
82104
105+{-| Combination of take and drop.
106+
107+ splitAt n xs == (take n xs, drop n xs)
108+-}
83109splitAt : Int -> Stream a -> ([a], Stream a)
84110splitAt n xs = case n of
85111 0 -> ([], xs)
86112 n -> let (heads, end) = splitAt (n - 1) (tail xs)
87113 in (head xs :: heads, end)
88114
89−sampleOn : Stream a -> Signal b -> Signal a
90−sampleOn str sig = let tails = foldp (\_ -> tail) str sig in
115+{-| Turn a stream into a signal of the elements of the stream,
116+ advancing through the stream whenever an event in the given signal is
117+ fired.
118+-}
119+sampleOn : Signal b -> Stream a -> Signal a
120+sampleOn sig str = let tails = foldp (\_ -> tail) str sig in
91121 head <~ tails