@@ -0,0 +1,50 @@
1+
2+module Lazy where
3+
4+{-| Library for efficient Lazy evaluation and Infinite Streams.
5+
6+-}
7+
8+import Basics ((-))
9+import Signal ((<~), foldp, Signal)
10+import Native.Lazy
11+
12+data Lazy a = L { run : () -> a }
13+
14+{-| Memoize a thunk so it is evaluated at most once -}
15+thunk : (() -> a) -> Lazy a
16+thunk t = L { run = (Native.Lazy.thunk t) }
17+
18+run : Lazy a -> a
19+run l = case l of L r -> r.run ()
20+
21+data Stream a = S { hd : a, tl : Lazy (Stream a) }
22+
23+hd : Stream a -> a
24+hd (S r) = r.hd
25+
26+tl : Stream a -> Stream a
27+tl (S r) = run (r.tl)
28+
29+repeat : a -> Stream a
30+repeat x = S { hd = x, tl = thunk (\() -> repeat x) }
31+
32+cycle : a -> [a] -> Stream a
33+cycle x xs = let cycle' ys = case ys of
34+ [] -> S { hd = x, tl = thunk (\() -> cycle' xs) }
35+ (y :: ys) -> S { hd = y, tl = thunk (\() -> cycle' ys) }
36+ in cycle' []
37+
38+zipWith : (a -> b -> c) -> Stream a -> Stream b -> Stream c
39+zipWith f xs ys = S { hd = f (hd xs) (hd ys)
40+ , tl = thunk (\() -> zipWith f (tl xs) (tl ys)) }
41+
42+observeWhen : Stream a -> Signal b -> Signal a
43+observeWhen str sig = let tls = foldp (\_ -> tl) str sig in
44+ hd <~ tls
45+
46+take : Int -> Stream a -> [a]
47+take n xs = case n of
48+ 0 -> []
49+ n -> hd xs :: take (n - 1) (tl xs)
50+