@@ -1,308 +1,308 @@
1Elm.Native.List = {};
1Elm.Native.List = {};
2Elm.Native.List.make = function(elm) {
2Elm.Native.List.make = function(elm) {
3− elm.Native = elm.Native || {};
3+ elm.Native = elm.Native || {};
4− elm.Native.List = elm.Native.List || {};
4+ elm.Native.List = elm.Native.List || {};
5− if (elm.Native.List.values) return elm.Native.List.values;
5+ if (elm.Native.List.values) return elm.Native.List.values;
6− if ('values' in Elm.Native.List)
6+ if ('values' in Elm.Native.List)
7− return elm.Native.List.values = Elm.Native.List.values;
7+ return elm.Native.List.values = Elm.Native.List.values;
9− var Utils = Elm.Native.Utils.make(elm);
9+ var Utils = Elm.Native.Utils.make(elm);
11− // TODO: Improve Nil handling
11+ // TODO: Improve Nil handling
12− // We can change places like: if (xs.ctor === '[]') ... to if (xs === Nil) ...
12+ // We can change places like: if (xs.ctor === '[]') ... to if (xs === Nil) ...
13− // but only if we're confident Nil can only be defined once.
13+ // but only if we're confident Nil can only be defined once.
14− // Currently (27Mar2013) each module can have different instantiations, so multiple Nil objects can exist
14+ // Currently (27Mar2013) each module can have different instantiations, so multiple Nil objects can exist
15− // (and if they're used interchangeably then direct object comparison fails where ctor doesn't).
15+ // (and if they're used interchangeably then direct object comparison fails where ctor doesn't).
16− // So, this can only be fixed when modules initialisation is also fixed.
16+ // So, this can only be fixed when modules initialisation is also fixed.
17− // The performance overhead of the .ctor calls is 5-10% according to jsperf (depending on fn + list size)
17+ // The performance overhead of the .ctor calls is 5-10% according to jsperf (depending on fn + list size)
18− // (on firefox 19)
18+ // (on firefox 19)
20− var Nil = { ctor:'[]' };
20+ var Nil = { ctor:'[]' };
22− // using freeze for every cons would be nice but is a huge (9x on firefox 19)
22+ // using freeze for every cons would be nice but is a huge (9x on firefox 19)
23− // performance penalty
23+ // performance penalty
24− function Cons(hd,tl) { return { ctor:"::", _0:hd, _1:tl }; }
24+ function Cons(hd,tl) { return { ctor:"::", _0:hd, _1:tl }; }
26− function throwError(f) {
26+ function throwError(f) {
27− throw new Error("Function '" + f + "' expects a non-empty list!");
27+ throw new Error("Function '" + f + "' expects a non-empty list!");
30− function toArray(xs) {
32− while (xs.ctor !== '[]') {
39− function fromArray(arr) {
30+ function toArray(xs) {
40− var out = Nil;
31+ var out = [];
41− for (var i = arr.length; i--; ) {
32+ while (xs.ctor !== '[]') {
42− out = Cons(arr[i], out);
33+ out.push(xs._0);
47− function range(lo,hi) {
39+ function fromArray(arr) {
48− var lst = Nil;
40+ var out = Nil;
49− if (lo <= hi) {
41+ for (var i = arr.length; i--; ) {
50− do { lst = Cons(hi,lst) } while (hi-->lo);
42+ out = Cons(arr[i], out);
47+ function range(lo,hi) {
50+ do { lst = Cons(hi,lst) } while (hi-->lo);
52− return lst
52+ return lst
55− function append(xs,ys) {
55+ function append(xs,ys) {
56− if (typeof xs === "string") { return xs.concat(ys); }
56+ if (typeof xs === "string") { return xs.concat(ys); }
57− if (xs.ctor === '[]') { return ys; }
57+ if (xs.ctor === '[]') { return ys; }
58− var root = Cons(xs._0, Nil);
58+ var root = Cons(xs._0, Nil);
59− var curr = root;
59+ var curr = root;
60− xs = xs._1;
60+ xs = xs._1;
61− while (xs.ctor !== '[]') {
61+ while (xs.ctor !== '[]') {
62− curr._1 = Cons(xs._0, Nil);
62+ curr._1 = Cons(xs._0, Nil);
63− xs = xs._1;
63+ xs = xs._1;
64− curr = curr._1;
64+ curr = curr._1;
70+ function head(v) { return v.ctor === '[]' ? throwError('head') : v._0; }
71+ function tail(v) { return v.ctor === '[]' ? throwError('tail') : v._1; }
74+ if (xs.ctor === '[]') { throwError('last'); }
76+ while (xs.ctor !== '[]') {
83+ function map(f, xs) {
85+ while (xs.ctor !== '[]') {
89+ return fromArray(arr);
67− return root;
92+ // f defined similarly for both foldl and foldr (NB: different from Haskell)
68− }
93+ // ie, foldl : (a -> b -> b) -> b -> [a] -> b
69−
94+ function foldl(f, b, xs) {
70− function head(v) { return v.ctor === '[]' ? throwError('head') : v._0; }
95+ var acc = b;
71− function tail(v) { return v.ctor === '[]' ? throwError('tail') : v._1; }
74− if (xs.ctor === '[]') { throwError('last'); }
76− while (xs.ctor !== '[]') {
96+ while (xs.ctor !== '[]') {
77− out = xs._0;
97+ acc = A2(f, xs._0, acc);
78− xs = xs._1;
98+ xs = xs._1;
103+ function foldr(f, b, xs) {
104+ var arr = toArray(xs);
106+ for (var i = arr.length; i--; ) {
107+ acc = A2(f, arr[i], acc);
112+ function foldl1(f, xs) {
113+ return xs.ctor === '[]' ? throwError('foldl1') : foldl(f, xs._0, xs._1);
116+ function foldr1(f, xs) {
117+ if (xs.ctor === '[]') { throwError('foldr1'); }
118+ var arr = toArray(xs);
119+ var acc = arr.pop();
120+ for (var i = arr.length; i--; ) {
121+ acc = A2(f, arr[i], acc);
126+ function scanl(f, b, xs) {
127+ var arr = toArray(xs);
129+ var len = arr.length;
130+ for (var i = 1; i < len; ++i) {
131+ arr[i] = A2(f, arr[i], arr[i-1]);
80− return out;
133+ return fromArray(arr);
83− function map(f, xs) {
85− while (xs.ctor !== '[]') {
89− return fromArray(arr);
135+
92− // f defined similarly for both foldl and foldr (NB: different from Haskell)
93− // ie, foldl : (a -> b -> b) -> b -> [a] -> b
94− function foldl(f, b, xs) {
136+ function scanl1(f, xs) {
95− var acc = b;
137+ return xs.ctor === '[]' ? throwError('scanl1') : scanl(f, xs._0, xs._1);
96− while (xs.ctor !== '[]') {
97− acc = A2(f, xs._0, acc);
140+ function filter(pred, xs) {
142+ while (xs.ctor !== '[]') {
143+ if (pred(xs._0)) { arr.push(xs._0); }
100− return acc;
146+ return fromArray(arr);
103− function foldr(f, b, xs) {
104− var arr = toArray(xs);
106− for (var i = arr.length; i--; ) {
107− acc = A2(f, arr[i], acc);
112− function foldl1(f, xs) {
149+ function length(xs) {
113− return xs.ctor === '[]' ? throwError('foldl1') : foldl(f, xs._0, xs._1);
150+ var out = 0;
114− }
151+ while (xs.ctor !== '[]') {
116− function foldr1(f, xs) {
153+ xs = xs._1;
117− if (xs.ctor === '[]') { throwError('foldr1'); }
154+ }
118− var arr = toArray(xs);
155+ return out;
119− var acc = arr.pop();
120− for (var i = arr.length; i--; ) {
121− acc = A2(f, arr[i], acc);
126− function scanl(f, b, xs) {
158+ function member(x, xs) {
127− var arr = toArray(xs);
159+ while (xs.ctor !== '[]') {
128− arr.unshift(b);
160+ if (Utils.eq(x,xs._0)) return true;
129− var len = arr.length;
161+ xs = xs._1;
130− for (var i = 1; i < len; ++i) {
162+ }
131− arr[i] = A2(f, arr[i], arr[i-1]);
163+ return false;
133− return fromArray(arr);
166+ function reverse(xs) { return fromArray(toArray(xs).reverse()); }
136− function scanl1(f, xs) {
168+ function concat(xss) {
137− return xs.ctor === '[]' ? throwError('scanl1') : scanl(f, xs._0, xs._1);
169+ if (xss.ctor === '[]') return xss;
138− }
170+ var arr = toArray(xss);
139−
171+ var xs = arr[arr.length-1];
140− function filter(pred, xs) {
172+ for (var i = arr.length-1; i--; ) {
141− var arr = [];
173+ xs = append(arr[i], xs);
142− while (xs.ctor !== '[]') {
174+ }
143− if (pred(xs._0)) { arr.push(xs._0); }
175+ return xs;
146− return fromArray(arr);
177+
149− function length(xs) {
178+ function all(pred, xs) {
151− while (xs.ctor !== '[]') {
179+ while (xs.ctor !== '[]') {
152− out += 1;
180+ if (!pred(xs._0)) return false;
153− xs = xs._1;
181+ xs = xs._1;
158− function member(x, xs) {
186+ function any(pred, xs) {
159− while (xs.ctor !== '[]') {
187+ while (xs.ctor !== '[]') {
160− if (Utils.eq(x,xs._0)) return true;
188+ if (pred(xs._0)) return true;
161− xs = xs._1;
189+ xs = xs._1;
164− }
194+ function zipWith(f, xs, ys) {
196+ while (xs.ctor !== '[]' && ys.ctor !== '[]') {
197+ arr.push(A2(f, xs._0, ys._0));
166− function reverse(xs) { return fromArray(toArray(xs).reverse()); }
201+ return fromArray(arr);
168− function concat(xss) {
169− if (xss.ctor === '[]') return xss;
170− var arr = toArray(xss);
171− var xs = arr[arr.length-1];
172− for (var i = arr.length-1; i--; ) {
173− xs = append(arr[i], xs);
178− function all(pred, xs) {
179− while (xs.ctor !== '[]') {
180− if (!pred(xs._0)) return false;
186− function any(pred, xs) {
204+ function zip(xs, ys) {
187− while (xs.ctor !== '[]') {
206+ while (xs.ctor !== '[]' && ys.ctor !== '[]') {
188− if (pred(xs._0)) return true;
207+ arr.push(Utils.Tuple2(xs._0, ys._0));
189− xs = xs._1;
208+ xs = xs._1;
211+ return fromArray(arr);
192− }
214+ function sort(xs) {
194− function zipWith(f, xs, ys) {
215+ function cmp(a,b) {
195− var arr = [];
216+ var ord = Utils.compare(a,b).ctor;
196− while (xs.ctor !== '[]' && ys.ctor !== '[]') {
217+ return ord=== 'EQ' ? 0 : ord === 'LT' ? -1 : 1;
197− arr.push(A2(f, xs._0, ys._0));
218+ }
198− xs = xs._1;
219+ return fromArray(toArray(xs).sort(cmp));
201− return fromArray(arr);
221+
202− }
222+ function nth(xs, n) {
203−
223+ return toArray(xs)[n];
204− function zip(xs, ys) {
206− while (xs.ctor !== '[]' && ys.ctor !== '[]') {
207− arr.push(Utils.Tuple2(xs._0, ys._0));
211− return fromArray(arr);
215− function cmp(a,b) {
226+ function take(n, xs) {
216− var ord = Utils.compare(a,b).ctor;
227+ var arr = [];
217− return ord=== 'EQ' ? 0 : ord === 'LT' ? -1 : 1;
228+ while (xs.ctor !== '[]' && n > 0) {
233+ return fromArray(arr);
219− return fromArray(toArray(xs).sort(cmp));
235+
222− function nth(xs, n) {
223− return toArray(xs)[n];
226− function take(n, xs) {
236+ function drop(n, xs) {
228− while (xs.ctor !== '[]' && n > 0) {
237+ while (xs.ctor !== '[]' && n > 0) {
230− xs = xs._1;
238+ xs = xs._1;
233− return fromArray(arr);
236− function drop(n, xs) {
244+ function repeat(n, x) {
237− while (xs.ctor !== '[]' && n > 0) {
247+ while (n > 0) {
238− xs = xs._1;
248+ if (n & 1) arr += pattern;
239− --n;
249+ n >>= 1, pattern += pattern;
251+ return fromArray(arr);
244− function repeat(n, x) {
248− if (n & 1) arr += pattern;
249− n >>= 1, pattern += pattern;
251− return fromArray(arr);
254− function join(sep, xss) {
254+ function join(sep, xss) {
255− if (typeof sep === 'string') return toArray(xss).join(sep);
255+ if (typeof sep === 'string') return toArray(xss).join(sep);
256− if (xss.ctor === '[]') return Nil;
256+ if (xss.ctor === '[]') return Nil;
257− var s = toArray(sep);
257+ var s = toArray(sep);
258− var out = toArray(xss._0);
258+ var out = toArray(xss._0);
259− xss = xss._1;
259+ xss = xss._1;
260− while (xss.ctor !== '[]') {
260+ while (xss.ctor !== '[]') {
261− out = out.concat(s, toArray(xss._0));
261+ out = out.concat(s, toArray(xss._0));
262− xss = xss._1;
262+ xss = xss._1;
264+ return fromArray(out);
264− return fromArray(out);
266+
267− Elm.Native.List.values = {
267+ Elm.Native.List.values = {
268− Nil:Nil,
268+ Nil:Nil,
269− Cons:Cons,
269+ Cons:Cons,
270− cons:F2(Cons),
270+ cons:F2(Cons),
271− toArray:toArray,
271+ toArray:toArray,
272− fromArray:fromArray,
272+ fromArray:fromArray,
273− range:range,
273+ range:range,
274− append:append,
274+ append:append,
276− head:head,
276+ head:head,
277− tail:tail,
277+ tail:tail,
278− last:last,
278+ last:last,
280− map:F2(map),
280+ map:F2(map),
281− foldl:F3(foldl),
281+ foldl:F3(foldl),
282− foldr:F3(foldr),
282+ foldr:F3(foldr),
284− foldl1:F2(foldl1),
284+ foldl1:F2(foldl1),
285− foldr1:F2(foldr1),
285+ foldr1:F2(foldr1),
286− scanl:F3(scanl),
286+ scanl:F3(scanl),
287− scanl1:F2(scanl1),
287+ scanl1:F2(scanl1),
288− filter:F2(filter),
288+ filter:F2(filter),
289− length:length,
289+ length:length,
290− member:F2(member),
290+ member:F2(member),
291− reverse:reverse,
291+ reverse:reverse,
292− concat:concat,
292+ concat:concat,
294− all:F2(all),
294+ all:F2(all),
295− any:F2(any),
295+ any:F2(any),
296− zipWith:F3(zipWith),
296+ zipWith:F3(zipWith),
297− zip:F2(zip),
297+ zip:F2(zip),
298− sort:sort,
298+ sort:sort,
299− nth:F2(nth),
299+ nth:F2(nth),
300− take:F2(take),
300+ take:F2(take),
301− drop:F2(drop),
301+ drop:F2(drop),
302− repeat:F2(repeat),
302+ repeat:F2(repeat),
304− join:F2(join)
304+ join:F2(join)
306− return elm.Native.List = Elm.Native.List.values;
306+ return elm.Native.List.values = Elm.Native.List.values;