on master help sign in
Add Library for Lazy Evaluation
c2a6b0dMax New
libraries/Lazy.elmnew file+50
@@ -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+
libraries/Native/Lazy.jsnew file+26
@@ -0,0 +1,26 @@
1+Elm.Native.Lazy = {};
2+Elm.Native.Lazy.make = function(elm) {
3+ elm.Native = elm.Native || {};
4+ elm.Native.Lazy = elm.Native.Lazy || {};
5+
6+ if (elm.Native.Lazy.values) return elm.Native.Lazy.values;
7+
8+ var Utils = Elm.Native.Utils.make(elm);
9+
10+ function thunk(f) {
11+ var value = {};
12+ var isEvaled = false;
13+ var memoed = function(x) {
14+ if(!isEvaled) {
15+ value = f(Utils.Tuple0);
16+ isEvaled = true;
17+ }
18+ return value;
19+ }
20+ return memoed;
21+ }
22+
23+ return elm.Native.Lazy.values = {
24+ thunk : thunk
25+ };
26+};