@@ -0,0 +1,121 @@
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' <| \() ->
54+ (x, map f (iterate f x))
56+{-| Create an infinite Stream of xs. -}
57+repeat : a -> Stream a
58+repeat x = iterate id x
60+{-| Cycle through the elements of the nonempty list (x :: xs) -}
61+cycle : a -> [a] -> Stream a
62+cycle x xs = let cycle' ys = case ys of
63+ [] -> cons' <| \() ->
67+{-| Apply a function to every element of a Stream. -}
68+map : (a -> b) -> Stream a -> Stream b
69+map f xs = cons' <| \() ->
70+ (f (head xs), map f (tail xs))
72+{-| Pairwise apply a stream of functions to a stream of inputs.
73+ Together with map, generalizes zipWith to n arguments.
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
78+apply : Stream (a -> b) -> Stream a -> Stream b
79+apply fs xs = zipWith (<|) fs xs
81+{-| Combine two streams, combining them into tuples pairwise. -}
82+zip : Stream a -> Stream b -> Stream (a, b)
83+zip = zipWith (\x y -> (x,y))
85+{-| Combine two streams, combining them with the given function. -}
86+zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
87+zipWith f xs ys = cons' <| \() ->
88+ (f (head xs) (head ys),
89+ zipWith f (tail xs) (tail ys))
91+{-| Reduce a Stream from the left, building an infinite stream of reductions. -}
92+scanl : (a -> b -> b) -> b -> Stream a -> Stream b
93+scanl f init xs = cons' <| \() ->
95+ scanl f (f (head xs) init) (tail xs))
97+{-| Compute the first n elements of a stream into a list. -}
98+take : Int -> Stream a -> [a]
99+take n xs = fst <| splitAt n xs
101+{-| Drop n elements from the front of a stream. -}
102+drop : Int -> Stream a -> Stream a
103+drop n xs = snd <| splitAt n xs
105+{-| Combination of take and drop.
107+ splitAt n xs == (take n xs, drop n xs)
109+splitAt : Int -> Stream a -> ([a], Stream a)
110+splitAt n xs = case n of
112+ n -> let (heads, end) = splitAt (n - 1) (tail xs)
113+ in (head xs :: heads, end)
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
119+sampleOn : Signal b -> Stream a -> Signal a
120+sampleOn sig str = let tails = foldp (\_ -> tail) str sig in