@@ -0,0 +1,125 @@
1+module Lazy.Stream ( head, tail
2+ , cons, cons', iterate, repeat, cycle
3+ , map, apply, zip, zipWith, scanl
8+{-| Library for Infinite Streams
11+@docs cons, cons', iterate, repeat, cycle
14+@docs head, tail, sampleOn, take, drop, splitAt
17+@docs map, apply, zip, zipWith, scanl
21+import Basics ((.), (<|), (-), id, fst, snd)
23+import Signal ((<~), foldp, Signal)
25+data Stream a = S (Lazy (a, Stream a))
27+unS : Stream a -> (a, Stream a)
30+{-| Compute the first element of a Stream -}
34+{-| Compute the next piece of a Stream -}
35+tail : Stream a -> Stream a
38+{-| Create a Stream -}
39+cons : a -> (() -> Stream a) -> Stream a
40+cons x txs = let mtxs = lazy txs in
44+{-| Lazily create a Stream. -}
45+cons' : (() -> (a, Stream a)) -> Stream a
48+{-| Create a stream of repeated applications of f to x:
50+ iterate f x = S.cons x (S.cons (f x) (S.cons (f (f x)) ...))
52+iterate : (a -> a) -> a -> Stream a
53+iterate f x = cons' <| \() ->
56+{-| Create an infinite Stream of xs. -}
57+repeat : a -> Stream a
58+repeat x = let go = cons x <| \() -> go
61+{-| Cycle through the elements of the nonempty list (x :: xs) -}
62+cycle : a -> [a] -> Stream a
63+cycle x xs = let cycle' ys = case ys of
65+ (y :: ys) -> cons y <| \() ->
71+{-| Apply a function to every element of a Stream. -}
72+map : (a -> b) -> Stream a -> Stream b
73+map f xs = cons' <| \() ->
74+ (f (head xs), map f (tail xs))
76+{-| Pairwise apply a stream of functions to a stream of inputs.
77+ Together with map, generalizes zipWith to n arguments.
79+ zipWith2 : (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
82+apply : Stream (a -> b) -> Stream a -> Stream b
83+apply fs xs = zipWith (<|) fs xs
85+{-| Combine two streams, combining them into tuples pairwise. -}
86+zip : Stream a -> Stream b -> Stream (a, b)
87+zip = zipWith (\x y -> (x,y))
89+{-| Combine two streams, combining them with the given function. -}
90+zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
91+zipWith f xs ys = cons' <| \() ->
92+ (f (head xs) (head ys),
93+ zipWith f (tail xs) (tail ys))
95+{-| Reduce a Stream from the left, building an infinite stream of reductions. -}
96+scanl : (a -> b -> b) -> b -> Stream a -> Stream b
97+scanl f init xs = cons' <| \() ->
99+ scanl f (f (head xs) init) (tail xs))
101+{-| Compute the first n elements of a stream into a list. -}
102+take : Int -> Stream a -> [a]
103+take n xs = fst <| splitAt n xs
105+{-| Drop n elements from the front of a stream. -}
106+drop : Int -> Stream a -> Stream a
107+drop n xs = snd <| splitAt n xs
109+{-| Combination of take and drop.
111+ splitAt n xs == (take n xs, drop n xs)
113+splitAt : Int -> Stream a -> ([a], Stream a)
114+splitAt n xs = case n of
116+ n -> let (heads, end) = splitAt (n - 1) (tail xs)
117+ in (head xs :: heads, end)
119+{-| 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
123+sampleOn : Signal b -> Stream a -> Signal a
124+sampleOn sig str = let tails = foldp (\_ -> tail) str sig in