on master help sign in
Add Stream docs and fix type of sampleOn.
08b88b7Max New
libraries/Lazy/Stream.elm+37−7
@@ -7,12 +7,12 @@ module Lazy.Stream ( head, tail
7
7
8{-| Library for Infinite Streams
8{-| Library for Infinite Streams
9
9
10+# Create
11+@docs cons, cons', iterate, repeat, cycle
12+
10# Observe
13# Observe
11@docs head, tail, sampleOn, take, drop, splitAt
14@docs head, tail, sampleOn, take, drop, splitAt
12
15
13−# Create
14−@docs cons', iterate, repeat, cycle
15−
16# Transform
16# Transform
17@docs map, apply, zip, zipWith, scanl
17@docs map, apply, zip, zipWith, scanl
18
18
@@ -27,65 +27,95 @@ data Stream a = S (Lazy (a, Stream a))
27unS : Stream a -> (a, Stream a)
27unS : Stream a -> (a, Stream a)
28unS (S t) = force t
28unS (S t) = force t
29
29
30+{-| Compute the first element of a Stream -}
30head : Stream a -> a
31head : Stream a -> a
31head = fst . unS
32head = fst . unS
32
33
34+{-| Compute the next piece of a Stream -}
33tail : Stream a -> Stream a
35tail : Stream a -> Stream a
34tail = snd . unS
36tail = snd . unS
35
37
38+{-| Create a Stream -}
36cons : a -> (() -> Stream a) -> Stream a
39cons : a -> (() -> Stream a) -> Stream a
37cons x txs = let mtxs = lazy txs in
40cons x txs = let mtxs = lazy txs in
38 S . lazy <| \() ->
41 S . lazy <| \() ->
39 (x, force mtxs)
42 (x, force mtxs)
40
43
44+{-| Lazily create a Stream. -}
41cons' : (() -> (a, Stream a)) -> Stream a
45cons' : (() -> (a, Stream a)) -> Stream a
42cons' = S . lazy
46cons' = S . lazy
43
47
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+-}
44iterate : (a -> a) -> a -> Stream a
52iterate : (a -> a) -> a -> Stream a
45iterate f x = cons' <| \() ->
53iterate f x = cons' <| \() ->
46 (x, map f (iterate f x))
54 (x, map f (iterate f x))
47
55
56+{-| Create an infinite Stream of xs. -}
48repeat : a -> Stream a
57repeat : a -> Stream a
49repeat x = iterate id x
58repeat x = iterate id x
50−
59+
60+{-| Cycle through the elements of the nonempty list (x :: xs) -}
51cycle : a -> [a] -> Stream a
61cycle : a -> [a] -> Stream a
52cycle x xs = let cycle' ys = case ys of
62cycle x xs = let cycle' ys = case ys of
53 [] -> cons' <| \() ->
63 [] -> cons' <| \() ->
54 (x, cycle' xs)
64 (x, cycle' xs)
55 in cycle' []
65 in cycle' []
56
66
67+{-| Apply a function to every element of a Stream. -}
57map : (a -> b) -> Stream a -> Stream b
68map : (a -> b) -> Stream a -> Stream b
58map f xs = cons' <| \() ->
69map f xs = cons' <| \() ->
59 (f (head xs), map f (tail xs))
70 (f (head xs), map f (tail xs))
60
71
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+-}
61apply : Stream (a -> b) -> Stream a -> Stream b
78apply : Stream (a -> b) -> Stream a -> Stream b
62apply fs xs = zipWith (<|) fs xs
79apply fs xs = zipWith (<|) fs xs
63−
80+
81+{-| Combine two streams, combining them into tuples pairwise. -}
64zip : Stream a -> Stream b -> Stream (a, b)
82zip : Stream a -> Stream b -> Stream (a, b)
65zip = zipWith (\x y -> (x,y))
83zip = zipWith (\x y -> (x,y))
66
84
85+{-| Combine two streams, combining them with the given function. -}
67zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
86zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
68zipWith f xs ys = cons' <| \() ->
87zipWith f xs ys = cons' <| \() ->
69 (f (head xs) (head ys),
88 (f (head xs) (head ys),
70 zipWith f (tail xs) (tail ys))
89 zipWith f (tail xs) (tail ys))
71
90
91+{-| Reduce a Stream from the left, building an infinite stream of reductions. -}
72scanl : (a -> b -> b) -> b -> Stream a -> Stream b
92scanl : (a -> b -> b) -> b -> Stream a -> Stream b
73scanl f init xs = cons' <| \() ->
93scanl f init xs = cons' <| \() ->
74 (init,
94 (init,
75 scanl f (f (head xs) init) (tail xs))
95 scanl f (f (head xs) init) (tail xs))
76
96
97+{-| Compute the first n elements of a stream into a list. -}
77take : Int -> Stream a -> [a]
98take : Int -> Stream a -> [a]
78take n xs = fst <| splitAt n xs
99take n xs = fst <| splitAt n xs
79
100
101+{-| Drop n elements from the front of a stream. -}
80drop : Int -> Stream a -> Stream a
102drop : Int -> Stream a -> Stream a
81drop n xs = snd <| splitAt n xs
103drop n xs = snd <| splitAt n xs
82
104
105+{-| Combination of take and drop.
106+
107+ splitAt n xs == (take n xs, drop n xs)
108+-}
83splitAt : Int -> Stream a -> ([a], Stream a)
109splitAt : Int -> Stream a -> ([a], Stream a)
84splitAt n xs = case n of
110splitAt n xs = case n of
85 0 -> ([], xs)
111 0 -> ([], xs)
86 n -> let (heads, end) = splitAt (n - 1) (tail xs)
112 n -> let (heads, end) = splitAt (n - 1) (tail xs)
87 in (head xs :: heads, end)
113 in (head xs :: heads, end)
88
114
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+-}
89−sampleOn : Stream a -> Signal b -> Signal a
119+sampleOn : Signal b -> Stream a -> Signal a
90−sampleOn str sig = let tails = foldp (\_ -> tail) str sig in
120+sampleOn sig str = let tails = foldp (\_ -> tail) str sig in
91 head <~ tails
121 head <~ tails