@@ -1,11 +1,24 @@
1−module Lazy.Stream ( hd, tl, mkStream, repeat, cycle
2− , map, apply, zip, zipWith, iterate
3− , take, observeWhen
1+module Lazy.Stream ( hd, tl
2+ , mkStream , iterate, repeat, cycle
3+ , map, apply, zip, zipWith, scanl
4+ , take, drop, splitAt
5+ , observeWhen
46 ) where
57
6−{-| Library for Infinite Streams -}
8+{-| Library for Infinite Streams
79
8−import Basics ((.), (<|), (-))
10+# Observe
11+@docs hd, tl, observeWhen, take, drop, splitAt
12+
13+# Create
14+@docs mkStream, iterate, repeat, cycle
15+
16+# Transform
17+@docs map, apply, zip, zipWith, scanl
18+
19+-}
20+
21+import Basics ((.), (<|), (-), id, fst, snd)
922import open Lazy
1023import Signal ((<~), foldp, Signal)
1124
@@ -20,9 +33,14 @@ tl (S t) = (run t).tl
2033mkStream : (() -> { hd : a, tl : Stream a }) -> Stream a
2134mkStream = S . thunk
2235
36+iterate : (a -> a) -> a -> Stream a
37+iterate f x = mkStream <| \() ->
38+ { hd = x
39+ , tl = map f (iterate f x)
40+ }
41+
2342repeat : a -> Stream a
24−repeat x = mkStream <| \() ->
25− { hd = x, tl = repeat x }
43+repeat x = iterate id x
2644
2745cycle : a -> [a] -> Stream a
2846cycle x xs = let cycle' ys = case ys of
@@ -52,16 +70,23 @@ zipWith f xs ys = mkStream <| \() ->
5270 , tl = zipWith f (tl xs) (tl ys)
5371 }
5472
55−iterate : (a -> a) -> a -> Stream a
56−iterate f x = mkStream <| \() ->
57− { hd = x
58− , tl = map f (iterate f x)
73+scanl : (a -> b -> b) -> b -> Stream a -> Stream b
74+scanl f init xs = mkStream <| \() ->
75+ { hd = init
76+ , tl = scanl f (f (hd xs) init) (tl xs)
5977 }
6078
6179take : Int -> Stream a -> [a]
62−take n xs = case n of
63− 0 -> []
64− n -> hd xs :: take (n - 1) (tl xs)
80+take n xs = fst <| splitAt n xs
81+
82+drop : Int -> Stream a -> Stream a
83+drop n xs = snd <| splitAt n xs
84+
85+splitAt : Int -> Stream a -> ([a], Stream a)
86+splitAt n xs = case n of
87+ 0 -> ([], xs)
88+ n -> let (hds, end) = splitAt (n - 1) (tl xs)
89+ in (hd xs :: hds, end)
6590
6691observeWhen : Stream a -> Signal b -> Signal a
6792observeWhen str sig = let tls = foldp (\_ -> tl) str sig in