@@ -8,33 +8,35 @@ Elm.Native.Array.make = function(elm) {
9 var List = Elm.Native.List.make(elm);
9 var List = Elm.Native.List.make(elm);
11− // An RRB-Tree has two distinct data types. A leaf which contains data as
11+ // A RRB-Tree has two distinct data types.
12− // an array in _1, and a height in _0, that is always 0. A node has in
12+ // Leaf -> "height" is always 0
13− // addition its size table in _2, while _1 contains an array of nodes or
13+ // "table" is an array of elements
14− // leaves.
14+ // Node -> "height" is always greater than 0
15−
15+ // "table" is an array of child nodes
16+ // "lengths" is an array of accumulated lengths of the child nodes
16− // M is the maximal node size. 32 seems fast. E is the allowed increase
18+ // M is the maximal table size. 32 seems fast. E is the allowed increase
17 // of search steps when concatting to find an index. Lower values will
19 // of search steps when concatting to find an index. Lower values will
18 // decrease balancing, but will increase search steps.
20 // decrease balancing, but will increase search steps.
19 var M = 32;
21 var M = 32;
20 var E = 2;
22 var E = 2;
22 // An empty array.
24 // An empty array.
23− var empty = { ctor:"_Array", _0:0, _1:new Array() };
25+ var empty = { ctor:"_Array", height:0, table:new Array() };
25 // Gets the value at index i recursively.
27 // Gets the value at index i recursively.
26 function get(i, a) {
28 function get(i, a) {
27− if (a._0 == 0) {
29+ if (a.height == 0) {
28− if (i < a._1.length) {
30+ if (i < a.table.length) {
29− return a._1[i];
31+ return a.table[i];
31− throw new Error("Index "+ i +" on the array is out of range. Check the length first or you safeGet.");
33+ throw new Error("Index "+ i +" is out of range. Check the length of your array first or use getSafe or getMaybe.");
35 var slot = getSlot(i, a);
37 var slot = getSlot(i, a);
36− var sub = slot > 0 ? a._2[slot-1] : 0;
38+ var sub = slot > 0 ? a.lengths[slot-1] : 0;
37− return get(i - sub, a._1[slot]);
39+ return get(i - sub, a.table[slot]);
40 // Sets the value at the index i. Only the nodes leading to i will get
42 // Sets the value at the index i. Only the nodes leading to i will get
@@ -44,14 +46,14 @@ Elm.Native.Array.make = function(elm) {
46 var newA = nodeCopy(a);
48 var newA = nodeCopy(a);
47− newA._1 = a._1.slice();
49+ newA.table = a.table.slice();
49− if (a._0 == 0) {
51+ if (a.height == 0) {
50− newA._1[i] = item;
52+ newA.table[i] = item;
52 var slot = getSlot(i, a);
54 var slot = getSlot(i, a);
53− var sub = slot > 0 ? a._2[slot-1] : 0;
55+ var sub = slot > 0 ? a.lengths[slot-1] : 0;
54− newA._1[slot] = set(i - sub, item, a._1[slot]);
56+ newA.table[slot] = set(i - sub, item, a.table[slot]);
56 return newA;
58 return newA;
@@ -63,7 +65,7 @@ Elm.Native.Array.make = function(elm) {
63 return pushed;
65 return pushed;
66− newTree = create(item, a._0);
68+ newTree = create(item, a.height);
67 return siblise(a, newTree);
69 return siblise(a, newTree);
@@ -72,10 +74,10 @@ Elm.Native.Array.make = function(elm) {
72 // null will be returned.
74 // null will be returned.
73 function push_(item, a) {
75 function push_(item, a) {
74 // Handle resursion stop at leaf level.
76 // Handle resursion stop at leaf level.
75− if (a._0 == 0) {
77+ if (a.height == 0) {
76− if (a._1.length < M) {
78+ if (a.table.length < M) {
77− var newA = { ctor:"_Array", _0:0, _1:a._1.slice() };
79+ var newA = { ctor:"_Array", height:0, table:a.table.slice() };
78− newA._1.push(item);
80+ newA.table.push(item);
79 return newA;
81 return newA;
81 return null;
83 return null;
@@ -89,19 +91,19 @@ Elm.Native.Array.make = function(elm) {
89 // be updated.
91 // be updated.
90 if (pushed != null) {
92 if (pushed != null) {
91 var newA = nodeCopy(a);
93 var newA = nodeCopy(a);
92− newA._1[newA._1.length - 1] = pushed;
94+ newA.table[newA.table.length - 1] = pushed;
93− newA._2[newA._2.length - 1]++;
95+ newA.lengths[newA.lengths.length - 1]++;
94 return newA
96 return newA
97 // When there was no space left, check if there is space left
99 // When there was no space left, check if there is space left
98 // for a new slot with a tree which contains only the item
100 // for a new slot with a tree which contains only the item
99 // at the bottom.
101 // at the bottom.
100− if (a._1.length < M) {
102+ if (a.table.length < M) {
101− var newSlot = create(item, a._0 - 1);
103+ var newSlot = create(item, a.height - 1);
102 var newA = nodeCopy(a);
104 var newA = nodeCopy(a);
103− newA._1.push(newSlot);
105+ newA.table.push(newSlot);
104− newA._2.push(newA._2[newA._2.length - 1] + length(newSlot));
106+ newA.lengths.push(newA.lengths[newA.lengths.length - 1] + length(newSlot));
105 return newA
107 return newA
107 return null;
109 return null;
@@ -109,53 +111,54 @@ Elm.Native.Array.make = function(elm) {
111 // Converts an array into a list of elements.
113 // Converts an array into a list of elements.
112− function elements(a) {
114+ function toList(a) {
113− return elements_(List.Nil, a);
115+ return toList_(List.Nil, a);
116− function elements_(list, a) {
118+ function toList_(list, a) {
117− for (var i = a._1.length - 1; i >= 0; i--) {
119+ for (var i = a.table.length - 1; i >= 0; i--) {
118− list = a._0 == 0 ? List.Cons(a._1[i], list) : elements_(list, a._1[i]);
120+ list = a.height == 0 ? List.Cons(a.table[i], list) : toList_(list, a.table[i]);
120 return list;
122 return list;
123− // Maps a function over an array.
125+ // Maps a function over the elements of an array.
124 function map(f, a) {
126 function map(f, a) {
125− var newA = { ctor:"_Array", _0:a._0, _1:new Array(a._1) };
127+ var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
126− if (a._0 > 0) { newA._2 = a._2; }
128+ if (a.height > 0) { newA.lengths = a.lengths; }
127− for (var i = 0; i < a._1.length; i++) {
129+ for (var i = 0; i < a.table.length; i++) {
128− newA._1[i] = a._0 == 0 ? f(a._1[i]) : map(f, a._1[i]);
130+ newA.table[i] = a.height == 0 ? f(a.table[i]) : map(f, a.table[i]);
130 return newA;
132 return newA;
135+ // Maps a function over the elements with their index as first argument.
133− function assocMap(f, a) {
136+ function indexedMap(f, a) {
134− var newA = { ctor:"_Array", _0:a._0, _1:new Array(a._1) };
137+ var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
135− if (a._0 > 0) { newA._2 = a._2; }
138+ if (a.height > 0) { newA.lengths = a.lengths; }
136− for (var i = 0; i < a._1.length; i++) {
139+ for (var i = 0; i < a.table.length; i++) {
137− newA._1[i] = a._0 == 0 ? A2(f, i, a._1[i]) : assocMap(f, a._1[i]);
140+ newA.table[i] = a.height == 0 ? A2(f, i, a.table[i]) : indexedMap(f, a.table[i]);
139 return newA;
142 return newA;
142 function foldl(f, b, a) {
145 function foldl(f, b, a) {
143− for (var i = a._1.length - 1; i >= 0; i--) {
146+ for (var i = a.table.length - 1; i >= 0; i--) {
144− b = A2(f, a._0 == 0 ? a._1[i] : foldl(f, b, a._1[i]), b);
147+ b = A2(f, a.height == 0 ? a.table[i] : foldl(f, b, a.table[i]), b);
146 return b;
149 return b;
149 function foldr(f, b, a) {
152 function foldr(f, b, a) {
150− for (var i = 0; i < a._1.length; i++) {
153+ for (var i = 0; i < a.table.length; i++) {
151− b = A2(f, a._0 == 0 ? a._1[i] : foldr(f, b, a._1[i]), b);
154+ b = A2(f, a.height == 0 ? a.table[i] : foldr(f, b, a.table[i]), b);
153 return b;
156 return b;
156− // Returns a sliced tree. The to is inclusive, but this may change,
159+ // Returns a sliced tree. "to" is inclusive, but this may change,
157 // when I understand, why e.g. JS does not handle it this way. :-)
160 // when I understand, why e.g. JS does not handle it this way. :-)
158− // If from or to is negative, they will select from the end on.
161+ // If "from" or "to" is negative, they will select from the end on.
159 // TODO: currently, it slices the right, then the left. This can be
162 // TODO: currently, it slices the right, then the left. This can be
160 // optimized.
163 // optimized.
161 function slice(from, to, a) {
164 function slice(from, to, a) {
@@ -170,15 +173,15 @@ Elm.Native.Array.make = function(elm) {
172 // Handle leaf level.
175 // Handle leaf level.
173− if (a._0 == 0) {
176+ if (a.height == 0) {
174− var newA = { ctor:"_Array", _0:0 };
177+ var newA = { ctor:"_Array", height:0 };
175− newA._1 = a._1.slice(0, to + 1);
178+ newA.table = a.table.slice(0, to + 1);
176 return newA;
179 return newA;
179 // Slice the right recursively.
182 // Slice the right recursively.
180 var right = getSlot(to, a);
183 var right = getSlot(to, a);
181− var sliced = sliceRight(to - (right > 0 ? a._2[right - 1] : 0), a._1[right]);
184+ var sliced = sliceRight(to - (right > 0 ? a.lengths[right - 1] : 0), a.table[right]);
183 // Maybe the a node is not even needed, as sliced contains the whole slice.
186 // Maybe the a node is not even needed, as sliced contains the whole slice.
184 if (right == 0) {
187 if (right == 0) {
@@ -186,11 +189,11 @@ Elm.Native.Array.make = function(elm) {
188 // Create new node.
191 // Create new node.
189− var newA = { ctor:"_Array", _0:a._0
192+ var newA = { ctor:"_Array", height:a.height
190− , _1:a._1.slice(0, right + 1)
193+ , table:a.table.slice(0, right + 1)
191− , _2:a._2.slice(0, right + 1) };
194+ , lengths:a.lengths.slice(0, right + 1) };
192− newA._1[right] = sliced;
195+ newA.table[right] = sliced;
193− newA._2[right] = length(sliced) + (right > 0 ? newA._2[right - 1] : 0);
196+ newA.lengths[right] = length(sliced) + (right > 0 ? newA.lengths[right - 1] : 0);
194 return newA;
197 return newA;
@@ -200,30 +203,30 @@ Elm.Native.Array.make = function(elm) {
202 // Handle leaf level.
205 // Handle leaf level.
203− if (a._0 == 0) {
206+ if (a.height == 0) {
204− var newA = { ctor:"_Array", _0:0 };
207+ var newA = { ctor:"_Array", height:0 };
205− newA._1 = a._1.slice(from, a._1.length + 1);
208+ newA.table = a.table.slice(from, a.table.length + 1);
206 return newA;
209 return newA;
209 // Slice the left recursively.
212 // Slice the left recursively.
210 var left = getSlot(from, a);
213 var left = getSlot(from, a);
211− var sliced = sliceLeft(from - (left > 0 ? a._2[left - 1] : 0), a._1[left]);
214+ var sliced = sliceLeft(from - (left > 0 ? a.lengths[left - 1] : 0), a.table[left]);
213 // Maybe the a node is not even needed, as sliced contains the whole slice.
216 // Maybe the a node is not even needed, as sliced contains the whole slice.
214− if (left == a._1.length - 1) {
217+ if (left == a.table.length - 1) {
215 return sliced;
218 return sliced;
218 // Create new node.
221 // Create new node.
219− var newA = { ctor:"_Array", _0:a._0
222+ var newA = { ctor:"_Array", height:a.height
220− , _1:a._1.slice(left, a._1.length + 1)
223+ , table:a.table.slice(left, a.table.length + 1)
221− , _2:new Array(a._1.length - left) };
224+ , lengths:new Array(a.table.length - left) };
222− newA._1[left] = sliced;
225+ newA.table[left] = sliced;
223 var len = 0;
226 var len = 0;
224− for (var i = 0; i < newA._1.length; i++) {
227+ for (var i = 0; i < newA.table.length; i++) {
225− len += length(newA._1[i]);
228+ len += length(newA.table[i]);
226− newA._2[i] = len;
229+ newA.lengths[i] = len;
229 return newA;
232 return newA;
@@ -233,12 +236,12 @@ Elm.Native.Array.make = function(elm) {
233 // TODO: Add support for concatting trees of different sizes. Current
236 // TODO: Add support for concatting trees of different sizes. Current
234 // behavior will just rise the lower tree and then concat them.
237 // behavior will just rise the lower tree and then concat them.
235 function concat(a, b) {
238 function concat(a, b) {
236− if (b._0 > a._0) { return concat(parentise(a, b._0), b); }
239+ if (b.height > a.height) { return concat(parentise(a, b.height), b); }
237− if (a._0 > b._0) { return concat(a, parentise(b, a._0)); }
240+ if (a.height > b.height) { return concat(a, parentise(b, a.height)); }
238− if (a._0 == 0) { return concat(parentise(a, 1), parentise(b, 1)); }
241+ if (a.height == 0) { return concat(parentise(a, 1), parentise(b, 1)); }
240 var c = concat_(a, b);
243 var c = concat_(a, b);
241− if (c[1]._1.length > 0) {
244+ if (c[1].table.length > 0) {
242 return siblise(c[0], c[1]);
245 return siblise(c[0], c[1]);
244 return c[0];
247 return c[0];
@@ -249,7 +252,7 @@ Elm.Native.Array.make = function(elm) {
249 // needs to be handled by the function, that called concat_. May be only
252 // needs to be handled by the function, that called concat_. May be only
250 // called for trees with an minimal height of 1.
253 // called for trees with an minimal height of 1.
251 function concat_(a, b) {
254 function concat_(a, b) {
252− if (a._0 == 1) {
255+ if (a.height == 1) {
253 // Check if balancing is needed and return based on that.
256 // Check if balancing is needed and return based on that.
254 var toRemove = calcToRemove(a, b);
257 var toRemove = calcToRemove(a, b);
255 if (toRemove <= E) {
258 if (toRemove <= E) {
@@ -263,29 +266,29 @@ Elm.Native.Array.make = function(elm) {
263 a = nodeCopy(a), b = nodeCopy(b);
266 a = nodeCopy(a), b = nodeCopy(b);
265 // Adjust the bottom right side of the new tree.
268 // Adjust the bottom right side of the new tree.
266− a._1[a._1.length - 1] = concated[0];
269+ a.table[a.table.length - 1] = concated[0];
267− a._2[a._2.length - 1] = length(concated[0])
270+ a.lengths[a.lengths.length - 1] = length(concated[0])
268− a._2[a._2.length - 1] += a._2.length > 1 ? a._2[a._2.length - 2] : 0;
271+ a.lengths[a.lengths.length - 1] += a.lengths.length > 1 ? a.lengths[a.lengths.length - 2] : 0;
270 // Adjust the bottom left side of the new tree.
273 // Adjust the bottom left side of the new tree.
271− if (concated[1]._1.length > 0) {
274+ if (concated[1].table.length > 0) {
272− b._1[0] = concated[1];
275+ b.table[0] = concated[1];
273− b._2[0] = length(concated[1]);
276+ b.lengths[0] = length(concated[1]);
274− for (var i = 1, len = length(b._1[0]); i < b._2.length; i++) {
277+ for (var i = 1, len = length(b.table[0]); i < b.lengths.length; i++) {
275− len += length(b._1[i]);
278+ len += length(b.table[i]);
276− b._2[i] = len;
279+ b.lengths[i] = len;
279− b._1.shift();
282+ b.table.shift();
280− for (var i = 1; i < b._2.length; i++) {
283+ for (var i = 1; i < b.lengths.length; i++) {
281− b._2[i] = b._2[i] - b._2[0];
284+ b.lengths[i] = b.lengths[i] - b.lengths[0];
283− b._2.shift();
286+ b.lengths.shift();
286 // Check if balancing is needed and return based on that.
289 // Check if balancing is needed and return based on that.
287 var toRemove = calcToRemove(a, b);
290 var toRemove = calcToRemove(a, b);
288− if (toRemove <= E || b._1.length == 0) {
291+ if (toRemove <= E || b.table.length == 0) {
289 return [a,b];
292 return [a,b];
@@ -295,18 +298,18 @@ Elm.Native.Array.make = function(elm) {
295 // Returns the extra search steps for E. Refer to the paper.
298 // Returns the extra search steps for E. Refer to the paper.
296 function calcToRemove(a, b) {
299 function calcToRemove(a, b) {
297 var subLengths = 0;
300 var subLengths = 0;
298− for (var i = 0; i < a._1.length; i++) {
301+ for (var i = 0; i < a.table.length; i++) {
299− subLengths += a._1[i]._1.length;
302+ subLengths += a.table[i].table.length;
301− for (var i = 0; i < b._1.length; i++) {
304+ for (var i = 0; i < b.table.length; i++) {
302− subLengths += b._1[i]._1.length;
305+ subLengths += b.table[i].table.length;
305− var toRemove = a._1.length + b._1.length
308+ var toRemove = a.table.length + b.table.length
306 return toRemove - (Math.floor((subLengths - 1) / M) + 1);
309 return toRemove - (Math.floor((subLengths - 1) / M) + 1);
309− // get2 and set2 are helpers for accessing over two arrays.
312+ // get2, set2 and saveSlot are helpers for accessing elements over two arrays.
310 function get2(a, b, index) {
313 function get2(a, b, index) {
311 return index < a.length ? a[index] : b[index - a.length];
314 return index < a.length ? a[index] : b[index - a.length];
@@ -319,59 +322,59 @@ Elm.Native.Array.make = function(elm) {
325+ function saveSlot(a, b, index, slot) {
326+ set2(a.table, b.table, index, slot);
328+ var l = (index == 0 || index == a.lengths.length) ?
329+ 0 : get2(a.lengths, a.lengths, index - 1);
330+ set2(a.lengths, b.lengths, index, l + length(slot));
322 // Creates a node or leaf with a given length at their arrays for perfomance.
333 // Creates a node or leaf with a given length at their arrays for perfomance.
323 // Is only used by shuffle.
334 // Is only used by shuffle.
324− function createNode(height, length) {
335+ function createNode(h, length) {
325 if (length < 0) { length = 0; }
336 if (length < 0) { length = 0; }
326− var a = { ctor:"_Array", _0:height, _1:new Array(length) };
337+ var a = { ctor:"_Array", height:h, table:new Array(length) };
327− if (height > 0) {
338+ if (h > 0) {
328− a._2 = new Array(length);
339+ a.lengths = new Array(length);
330 return a;
341 return a;
333− function saveSlot(a, b, index, slot) {
334− set2(a._1, b._1, index, slot);
336− var l = (index == 0 || index == a._2.length) ?
337− 0 : get2(a._2, a._2, index - 1);
338− set2(a._2, b._2, index, l + length(slot));
341 // Returns an array of two balanced nodes.
344 // Returns an array of two balanced nodes.
342 function shuffle(a, b, toRemove) {
345 function shuffle(a, b, toRemove) {
343− var newA = createNode(a._0, Math.min(M, a._1.length + b._1.length - toRemove));
346+ var newA = createNode(a.height, Math.min(M, a.table.length + b.table.length - toRemove));
344− var newB = createNode(a._0, newA._1.length - (a._1.length + b._1.length - toRemove));
347+ var newB = createNode(a.height, newA.table.length - (a.table.length + b.table.length - toRemove));
346 // Skip the slots with size M. More precise: copy the slot references
349 // Skip the slots with size M. More precise: copy the slot references
347 // to the new node
350 // to the new node
348 var read = 0;
351 var read = 0;
349− while (get2(a._1, b._1, read)._1.length % M == 0) {
352+ while (get2(a.table, b.table, read).table.length % M == 0) {
350− set2(newA._1, newB._1, read, get2(a._1, b._1, read));
353+ set2(newA.table, newB.table, read, get2(a.table, b.table, read));
351− set2(newA._2, newB._2, read, get2(a._2, b._2, read));
354+ set2(newA.lengths, newB.lengths, read, get2(a.lengths, b.lengths, read));
355 // Pulling items from left to right, caching in a slot before writing
358 // Pulling items from left to right, caching in a slot before writing
356 // it into the new nodes.
359 // it into the new nodes.
357 var write = read;
360 var write = read;
358− var slot = new createNode(a._0 - 1, 0);
361+ var slot = new createNode(a.height - 1, 0);
359 var from = 0;
362 var from = 0;
361 // If the current slot is still containing data, then there will be at
364 // If the current slot is still containing data, then there will be at
362 // least one more write, so we do not break this loop yet.
365 // least one more write, so we do not break this loop yet.
363− while (read - write - (slot._1.length > 0 ? 1 : 0) < toRemove) {
366+ while (read - write - (slot.table.length > 0 ? 1 : 0) < toRemove) {
364 // Find out the max possible items for copying.
367 // Find out the max possible items for copying.
365− var source = get2(a._1, b._1, read);
368+ var source = get2(a.table, b.table, read);
366− var to = Math.min(M - slot._1.length, source._1.length)
369+ var to = Math.min(M - slot.table.length, source.table.length)
368 // Copy and adjust size table.
371 // Copy and adjust size table.
369− slot._1 = slot._1.concat(source._1.slice(from, to));
372+ slot.table = slot.table.concat(source.table.slice(from, to));
370− if (slot._0 > 0) {
373+ if (slot.height > 0) {
371− var len = slot._2.length;
374+ var len = slot.lengths.length;
372 for (var i = len; i < len + to - from; i++) {
375 for (var i = len; i < len + to - from; i++) {
373− slot._2[i] = length(slot._1[i]);
376+ slot.lengths[i] = length(slot.table[i]);
374− slot._2[i] += (i > 0 ? slot._2[i - 1] : 0);
377+ slot.lengths[i] += (i > 0 ? slot.lengths[i - 1] : 0);
@@ -379,60 +382,60 @@ Elm.Native.Array.make = function(elm) {
380 // Only proceed to next slots[i] if the current one was
383 // Only proceed to next slots[i] if the current one was
381 // fully copied.
384 // fully copied.
382− if (source._1.length <= to) {
385+ if (source.table.length <= to) {
383 read++; from = 0;
386 read++; from = 0;
386 // Only create a new slot if the current one is filled up.
389 // Only create a new slot if the current one is filled up.
387− if (slot._1.length == M) {
390+ if (slot.table.length == M) {
388 saveSlot(newA, newB, write, slot);
391 saveSlot(newA, newB, write, slot);
389− slot = createNode(a._0 - 1,0);
392+ slot = createNode(a.height - 1,0);
394 // Cleanup after the loop. Copy the last slot into the new nodes.
397 // Cleanup after the loop. Copy the last slot into the new nodes.
395− if (slot._1.length > 0) {
398+ if (slot.table.length > 0) {
396 saveSlot(newA, newB, write, slot);
399 saveSlot(newA, newB, write, slot);
400 // Shift the untouched slots to the left
403 // Shift the untouched slots to the left
401− while (read < a._1.length + b._1.length ) {
404+ while (read < a.table.length + b.table.length ) {
402− saveSlot(newA, newB, write, get2(a._1, b._1, read));
405+ saveSlot(newA, newB, write, get2(a.table, b.table, read));
403 read++; write++;
406 read++; write++;
406 return [newA, newB];
409 return [newA, newB];
409− // Helper functions
412+ // Navigation functions
410− function botRight(a) { return a._1[a._1.length - 1]; }
413+ function botRight(a) { return a.table[a.table.length - 1]; }
411− function botLeft(a) { return a._1[0]; }
414+ function botLeft(a) { return a.table[0]; }
413− // Copies a node for updating. Note that you should not use
416+ // Copies a node for updating. Note that you should not use this if
414− // this if only updating one of _1 and _2 for performance reasons.
417+ // only updating only one of "table" or "lengths" for performance reasons.
415 function nodeCopy(a) {
418 function nodeCopy(a) {
416− var newA = { ctor:"_Array", _0:a._0
419+ var newA = { ctor:"_Array", height:a.height
417− , _1:a._1.slice() };
420+ , table:a.table.slice() };
418− if (a._0 > 0) { newA._2 = a._2.slice(); }
421+ if (a.height > 0) { newA.lengths = a.lengths.slice(); }
419 return newA;
422 return newA;
422 // Returns how many items are in the tree.
425 // Returns how many items are in the tree.
423 function length(a) {
426 function length(a) {
424− if (a._0 == 0) {
427+ if (a.height == 0) {
425− return a._1.length;
428+ return a.table.length;
427− return a._2[a._2.length - 1];
430+ return a.lengths[a.lengths.length - 1];
431− // Calculates in which slot the item probably is, then
434+ // Calculates in which slot of "table" the item probably is, then
432− // find the exact slot in the size table ._2. Returns the index.
435+ // find the exact slot via forward searching in "lengths". Returns the index.
433 function getSlot(i, a) {
436 function getSlot(i, a) {
434− var slot = Math.floor(i / (Math.pow(M, a._0)));
437+ var slot = Math.floor(i / (Math.pow(M, a.height)));
435− while (a._2[slot] <= i) {
438+ while (a.lengths[slot] <= i) {
438 return slot;
441 return slot;
@@ -440,45 +443,45 @@ Elm.Native.Array.make = function(elm) {
441 // Recursively creates a tree with a given height containing
444 // Recursively creates a tree with a given height containing
442 // only the given item.
445 // only the given item.
443− function create(item, height) {
446+ function create(item, h) {
444− if (height == 0) {
447+ if (h == 0) {
445− return { ctor:"_Array", _0:0
448+ return { ctor:"_Array", height:0
446− , _1:[item] };
449+ , table:[item] };
448− return { ctor:"_Array", _0:height
451+ return { ctor:"_Array", height:h
449− , _1:[create(item, height - 1)]
452+ , table:[create(item, h - 1)]
450− , _2:[1] };
453+ , lengths:[1] };
454 // Recursively creates a tree that contains the given tree.
457 // Recursively creates a tree that contains the given tree.
455− function parentise(tree, height) {
458+ function parentise(tree, h) {
456− if (height == tree._0) {
459+ if (h == tree.height) {
457 return tree;
460 return tree;
459− return { ctor:"_Array", _0:height
462+ return { ctor:"_Array", height:h
460− , _1:[parentise(tree, height - 1)]
463+ , table:[parentise(tree, h - 1)]
461− , _2:[length(tree)] };
464+ , lengths:[length(tree)] };
465 // Emphasizes blood brotherhood beneath two trees.
468 // Emphasizes blood brotherhood beneath two trees.
466 function siblise(a, b) {
469 function siblise(a, b) {
467− return { ctor:"_Array", _0:a._0 + 1
470+ return { ctor:"_Array", height:a.height + 1
468− , _1:[a, b]
471+ , table:[a, b]
469− , _2:[length(a), length(a) + length(b)] };
472+ , lengths:[length(a), length(a) + length(b)] };
472 Elm.Native.Array.values = {
475 Elm.Native.Array.values = {
473 empty:empty,
476 empty:empty,
474− elements:elements,
477+ toList:toList,
475 concat:F2(concat),
478 concat:F2(concat),
476 push:F2(push),
479 push:F2(push),
477 slice:F3(slice),
480 slice:F3(slice),
478 get:F2(get),
481 get:F2(get),
479 set:F3(set),
482 set:F3(set),
480 map:F2(map),
483 map:F2(map),
481− assocMap:F2(assocMap),
484+ indexedMap:F2(indexedMap),
482 foldl:F3(foldl),
485 foldl:F3(foldl),
483 foldr:F3(foldr),
486 foldr:F3(foldr),
484 length:length
487 length:length