1Elm.Native.List = function(elm) {
4 elm.Native = elm.Native || {};
5 if (elm.Native.List) return elm.Native.List;
6 if ('values' in Elm.Native.List) return elm.Native.List = Elm.Native.List.values
8 var Utils = Elm.Native.Utils(elm);
10 // TODO: Improve Nil handling
11 // We can change places like: if (xs.ctor === 'Nil') ... to if (xs === Nil) ...
12 // but only if we're confident Nil can only be defined once.
13 // Currently (27Mar2013) each module can have different instantiations, so multiple Nil objects can exist
14 // (and if they're used interchangeably then direct object comparison fails where ctor doesn't).
15 // So, this can only be fixed when modules initialisation is also fixed.
16 // The performance overhead of the .ctor calls is 5-10% according to jsperf (depending on fn + list size)
19 // freeze is universally supported and as a singleton introduces little performance penalty
20 // for a small amount of object safety
21 var Nil = Object.freeze({ ctor:'Nil' });
23 // using freeze for every cons would be nice but is a huge (9x on firefox 19) performance penalty
24 function Cons(hd,tl) { return { ctor:"Cons", _0:hd, _1:tl }; }
26 function throwError(f) {
27 throw new Error("Function '" + f + "' expects a non-empty list!");
30 function toArray(xs) {
32 while (xs.ctor !== 'Nil') {
39 function fromArray(arr) {
41 for (var i = arr.length; i--; ) {
42 out = Cons(arr[i], out);
47 function range(lo,hi) {
50 do { lst = Cons(hi,lst) } while (hi-->lo);
55 function append(xs,ys) {
56 if (typeof xs === "string") { return xs.concat(ys); }
57 if (xs.ctor === 'Nil') { return ys; }
58 var root = Cons(xs._0, Nil);
61 while (xs.ctor !== 'Nil') {
62 curr._1 = Cons(xs._0, Nil);
70 function head(v) { return v.ctor === 'Nil' ? throwError('head') : v._0; }
71 function tail(v) { return v.ctor === 'Nil' ? throwError('tail') : v._1; }
74 if (xs.ctor === 'Nil') { throwError('last'); }
76 while (xs.ctor !== 'Nil') {
85 while (xs.ctor !== 'Nil') {
89 return fromArray(arr);
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) {
96 while (xs.ctor !== 'Nil') {
97 acc = A2(f, xs._0, acc);
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 === 'Nil' ? throwError('foldl1') : foldl(f, xs._0, xs._1);
116 function foldr1(f, xs) {
117 if (xs.ctor === 'Nil') { throwError('foldr1'); }
118 var arr = toArray(xs);
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]);
133 return fromArray(arr);
136 function scanl1(f, xs) {
137 return xs.ctor === 'Nil' ? throwError('scanl1') : scanl(f, xs._0, xs._1);
140 function filter(pred, xs) {
142 while (xs.ctor !== 'Nil') {
143 if (pred(xs._0)) { arr.push(xs._0); }
146 return fromArray(arr);
149 function length(xs) {
151 while (xs.ctor !== 'Nil') {
158 function member(x, xs) {
159 while (xs.ctor !== 'Nil') {
160 if (Utils.eq(x,xs._0)) return true;
166 function reverse(xs) { return fromArray(toArray(xs).reverse()); }
168 function concat(xss) {
169 if (xss.ctor === 'Nil') 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 !== 'Nil') {
180 if (!pred(xs._0)) return false;
186 function any(pred, xs) {
187 while (xs.ctor !== 'Nil') {
188 if (pred(xs._0)) return true;
194 function zipWith(f, xs, ys) {
196 while (xs.ctor !== 'Nil' && ys.ctor !== 'Nil') {
197 arr.push(A2(f, xs._0, ys._0));
201 return fromArray(arr);
204 function zip(xs, ys) {
206 while (xs.ctor !== 'Nil' && ys.ctor !== 'Nil') {
207 arr.push(Utils.Tuple2(xs._0, ys._0));
211 return fromArray(arr);
216 var ord = Utils.compare(a,b).ctor;
217 return ord=== 'EQ' ? 0 : ord === 'LT' ? -1 : 1;
219 return fromArray(toArray(xs).sort(cmp));
222 function take(n, xs) {
224 while (xs.ctor !== 'Nil' && n > 0) {
229 return fromArray(arr);
232 function drop(n, xs) {
233 while (xs.ctor !== 'Nil' && n > 0) {
240 function join(sep, xss) {
241 if (xss.ctor === 'Nil') return Nil;
242 var s = toArray(sep);
243 var out = toArray(xss._0);
245 while (xss.ctor !== 'Nil') {
246 out = out.concat(s, toArray(xss._0));
249 return fromArray(out);
252 function split(sep, xs) {
254 var array = toArray(xs);
255 var s = toArray(sep);
258 for (var i = array.length; i--; ) {
259 out = Cons(Cons(array[i],Nil), out);
264 for (var i = array.length - slen; i >= 0; --i) {
266 for (var j = slen; j--; ) {
267 if (!Utils.eq(array[i+j], s[j])) { match = false; break; }
270 out = Cons(temp,out);
274 temp = Cons(array[i+j], temp);
277 for (var j = slen-1; j--; ) {
278 temp = Cons(array[j], temp);
280 out = Cons(temp, out);
284 Elm.Native.List.values = {
321 return elm.Native.List = Elm.Native.List.values;
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list