on master help sign in
Work on docs and simplify/normalize API

Did some renaming: fill -> repeat concat -> append getSafe -> getWithDefault Added initialize function. Removed some non-core functions that were implemented with lists (zip, zipWith). Don’t want to provide functions with a slow implementation and give people a false expectation of speed. These can definitely be added back at some point because they are pretty handy. Also got rid of indices because I think it’s easy enough to do [ 0 .. A.length array - 1 ] and it’s not so common that this would be desirable in the first place. Also, how do you spell that damn word?

commitea54e588ef521a37774aee48d9d7373492b4e110 authorEvan Czaplicki <info@elm-lang.org> dateWed 2 Apr 2014, 23:32 (13 years ago) parent9fb9f91
2 files changed+80−92
libraries/Array.elm+62−74 libraries/Native/Array.js+18−18
libraries/Array.elm+62−74
@@ -1,23 +1,23 @@
11module Array where
22
3−{-| A library for immutable arrays. The elements in an array must have the same
4−type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast
5−reads, updates, and concatenation.
3+{-| A library for fast immutable arrays. The elements in an array must have the
4+same type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast
5+reads, updates, and appends.
66
7−If you use more then one map or zip function on an array, consider turning it
8−into a list before operating on it, and then turning it back into an array.
7+# Creating Arrays
8+@docs empty, repeat, initialize, fromList
99
1010# Basics
11−@docs empty, length, get, getMaybe, getSafe
11+@docs length, push, append
1212
13−# Putting Arrays Together
14−@docs fill, fromList, concat, set, updates, push
13+# Get and Set
14+@docs get, getMaybe, getWithDefault, set
1515
1616# Taking Arrays Apart
17−@docs toList, toIndexedList, indices, slice
17+@docs toList, toIndexedList, slice
1818
19−# Mapping, folding, zipping
20−@docs map, indexedMap, foldl, foldr, zip, zipWith
19+# Mapping and Folding
20+@docs map, indexedMap, foldl, foldr
2121-}
2222
2323import Native.Array
@@ -27,17 +27,32 @@ import List
2727
2828data Array a = Array
2929
30−{-| Fills an array with a given length and a default element.
30+-- TODO: make this a native function
31+{-| Initialize an array. `initialize n f` creates an array of length `n` with
32+the element at index `i` initialized to the result of `(f i)`.
3133
32− fill 3 5 == fromList [5,5,5]
34+ initialize 4 id == fromList [0,1,2,3]
35+ initialize 4 (\n -> n*n) == fromList [0,1,4,9]
36+ initialize 4 (always 0) == fromList [0,0,0,0]
3337-}
34−fill : Int -> a -> Array a
35−fill len e = fromList <| List.map (always e) [1..len]
38+initialize : Int -> (Int -> a) -> Array a
39+initialize n initializer =
40+ fromList <| List.map initializer [ 0 .. n - 1 ]
41+
42+{-| Creates an array with a given length, filled with a default element.
43+
44+ repeat 5 0 == fromList [0,0,0,0,0]
45+ repeat 3 "cat" == fromList ["cat","cat","cat"]
46+
47+Notice that `repeat 3 x` is the same as `initialize 3 (always x)`.
48+-}
49+repeat : Int -> a -> Array a
50+repeat n e = initialize n (always e)
3651
3752-- TODO: make this a native function.
3853{-| Create an array from a list. -}
3954fromList : [a] -> Array a
40−fromList = List.foldl (Native.Array.push) Native.Array.empty
55+fromList xs = List.foldl Native.Array.push Native.Array.empty xs
4156
4257{-| Create a list of elements from an array.
4358
@@ -46,24 +61,19 @@ fromList = List.foldl (Native.Array.push) Native.Array.empty
4661toList : Array a -> [a]
4762toList = Native.Array.toList
4863
49−{-| Create a list of the possible indices of an array.
50−
51− indices (fromList [3,5,8] == [0,1,2])
52−-}
53−indices : Array a -> [Int]
54−indices a = [0..Native.Array.length a - 1]
55−
5664-- TODO: make this a native function.
57−{-| Create a list of tuples (Index, Element) from an array.
65+{-| Create an indexed list from an array. Each element of the array will be
66+paired with its index.
5867
59− toIndexedList (fromList [3,5,8]) == [(0,3), (1,5), (2,8)]
68+ toIndexedList (fromList ["cat","dog"]) == [(0,"cat"), (1,"dog")]
6069-}
6170toIndexedList : Array a -> [(Int, a)]
62−toIndexedList a = List.zip (indices a) (Native.Array.toList a)
71+toIndexedList array =
72+ List.zip [ 0 .. Native.Array.length array - 1 ] (Native.Array.toList array)
6373
6474{-| Apply a function on every element in an array.
6575
66− map (\x -> x*x) (fromList [1,2,3]) == fromList [1,4,9]
76+ map sqrt (fromList [1,4,9]) == fromList [1,2,3]
6777-}
6878map : (a -> b) -> Array a -> Array b
6979map = Native.Array.map
@@ -77,35 +87,18 @@ indexedMap = Native.Array.indexedMap
7787
7888{-| Reduce an array from the left.
7989
80− foldl (+) 0 (fill 3 5) == 15
90+ foldl (::) [] (fromList [1,2,3]) == [3,2,1]
8191-}
8292foldl : (a -> b -> b) -> b -> Array a -> b
8393foldl = Native.Array.foldl
8494
8595{-| Reduce an array from the right.
8696
87− foldr (::) [] (fromList [1,2,3]) == [3,2,1]
97+ foldr (+) 0 (repeat 3 5) == 15
8898-}
8999foldr : (a -> b -> b) -> b -> Array a -> b
90100foldr = Native.Array.foldr
91101
92−{-| Zip the elements of two arrays via a tuple into a new array. If one array is
93−longer, the extra elements are dropped.
94−
95− zip (fromList [1,2,3,4]) (fromList [0,0,0]) = fromList [(1,0), (2,0), (3,0)]
96−-}
97−zip : Array a -> Array b -> Array (a,b)
98−zip = zipWith (,)
99−
100−{-| Zips the elements of two arrays via a function into a new array. If one array
101−is longer, the extra elements are dropped.
102−
103− zipWith (+) (fill 3 5) (fill 5 8) == fill 3 13
104−-}
105−zipWith : (a -> b -> c) -> Array a -> Array b -> Array c
106−zipWith f a b =
107− fromList <| List.zipWith f (Native.Array.toList a) (Native.Array.toList b)
108−
109102{-| Return an empty array.
110103
111104 length empty == 0
@@ -121,7 +114,7 @@ push : a -> Array a -> Array a
121114push = Native.Array.push
122115
123116{-| Return the element at the index. Breaks, if index is out of range. If the
124−array length is unkown, use safeGet oder getWithDefault.
117+array length is unkown, use withDefaultGet oder getWithDefault.
125118
126119 get 2 (A.fromList [3,2,1]) == 1
127120-}
@@ -130,46 +123,41 @@ get = Native.Array.get
130123
131124{-| Return Just the element at the index or Nothing if the index is out of range.
132125
133− getMaybe 2 (A.fromList [3,2,1]) == Just 2
134− getMaybe 5 (A.fromList [3,2,1]) == Nothing
126+ getMaybe 2 (fromList [3,2,1]) == Just 2
127+ getMaybe 5 (fromList [3,2,1]) == Nothing
135128-}
136129getMaybe : Int -> Array a -> Maybe a
137−getMaybe i array = if Native.Array.length array > i
138− then Just (Native.Array.get i array)
139− else Nothing
130+getMaybe i array =
131+ if Native.Array.length array > i
132+ then Just (Native.Array.get i array)
133+ else Nothing
140134
141135{-| Get the element at the index. If the index is out of range, the given default
142136element is returned.
143137
144− getSafe 0 2 (A.fromList [3,2,1]) == 1
145− getSafe 0 5 (A.fromList [3,2,1]) == 0
138+ getWithDefault 0 2 (fromList [3,2,1]) == 1
139+ getWithDefault 0 5 (fromList [3,2,1]) == 0
146140-}
147−getSafe : a -> Int -> Array a -> a
148−getSafe default i array = if Native.Array.length array > i
149− then Native.Array.get i array else default
141+getWithDefault : a -> Int -> Array a -> a
142+getWithDefault default i array =
143+ if Native.Array.length array > i
144+ then Native.Array.get i array
145+ else default
150146
151−{-| Set the element at the index. Returns the updated array, or if the index is
152−out of range, the unaltered array.
147+{-| Set the element at a particular index. Returns an updated array.
148+If the index is out of range, the array is unaltered.
153149
154150 set 1 7 (fromList [1,2,3]) == fromList [1,7,3]
155151-}
156152set : Int -> a -> Array a -> Array a
157153set = Native.Array.set
158154
159−{-| Update an array with a a list tuples, wherein the first Int is the index.
160−
161− updates [(1,7),(2,8)] (fill 3 1) == fromList [1,7,8]
162−-}
163−updates : [(Int, a)] -> Array a -> Array a
164−updates us array = List.foldl (uncurry Native.Array.set) array us
165−
166155{-| Slice an array given a range. The selection is inclusive, so the last
167156element in the selection will also be in the new array. This may change in the
168−future.
169−You can select from the end by giving a negative Int.
157+future. You can select from the end by giving a negative Int.
170158
171− slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
172− slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
159+ slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
160+ slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
173161 slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
174162-}
175163slice : Int -> Int -> Array a -> Array a
@@ -182,9 +170,9 @@ slice = Native.Array.slice
182170length : Array a -> Int
183171length = Native.Array.length
184172
185−{-| Concat two arrays to a new one.
173+{-| Append two arrays to a new one.
186174
187− concat (fill 3 1) (fill 4 2) == fromList [1,1,1,2,2,2,2]
175+ append (array 2 42) (array 3 81) == fromList [42,42,81,81,81]
188176-}
189−concat : Array a -> Array a -> Array a
190−concat = Native.Array.concat
177+append : Array a -> Array a -> Array a
178+append = Native.Array.append
libraries/Native/Array.js+18−18
@@ -232,15 +232,15 @@ Elm.Native.Array.make = function(elm) {
232232 return newA;
233233 }
234234
235− // Concats two trees.
236− // TODO: Add support for concatting trees of different sizes. Current
237− // behavior will just rise the lower tree and then concat them.
238− function concat(a, b) {
239− if (b.height > a.height) { return concat(parentise(a, b.height), b); }
240− if (a.height > b.height) { return concat(a, parentise(b, a.height)); }
241− if (a.height == 0) { return concat(parentise(a, 1), parentise(b, 1)); }
242−
243− var c = concat_(a, b);
235+ // Appends two trees.
236+ // TODO: Add support for appending trees of different sizes. Current
237+ // behavior will just rise the lower tree and then append them.
238+ function append(a,b) {
239+ if (b.height > a.height) { return append(parentise(a, b.height), b); }
240+ if (a.height > b.height) { return append(a, parentise(b, a.height)); }
241+ if (a.height == 0) { return append(parentise(a, 1), parentise(b, 1)); }
242+
243+ var c = append_(a, b);
244244 if (c[1].table.length > 0) {
245245 return siblise(c[0], c[1]);
246246 } else {
@@ -249,9 +249,9 @@ Elm.Native.Array.make = function(elm) {
249249 }
250250
251251 // Returns an array of two nodes. The second node _may_ be empty. This case
252− // needs to be handled by the function, that called concat_. May be only
252+ // needs to be handled by the function, that called append_. May be only
253253 // called for trees with an minimal height of 1.
254− function concat_(a, b) {
254+ function append_(a, b) {
255255 if (a.height == 1) {
256256 // Check if balancing is needed and return based on that.
257257 var toRemove = calcToRemove(a, b);
@@ -262,18 +262,18 @@ Elm.Native.Array.make = function(elm) {
262262 return shuffle(a, b, toRemove);
263263 }
264264
265− var concated = concat_(botRight(a), botLeft(b));
265+ var appended = append_(botRight(a), botLeft(b));
266266 a = nodeCopy(a), b = nodeCopy(b);
267267
268268 // Adjust the bottom right side of the new tree.
269− a.table[a.table.length - 1] = concated[0];
270− a.lengths[a.lengths.length - 1] = length(concated[0])
269+ a.table[a.table.length - 1] = appended[0];
270+ a.lengths[a.lengths.length - 1] = length(appended[0])
271271 a.lengths[a.lengths.length - 1] += a.lengths.length > 1 ? a.lengths[a.lengths.length - 2] : 0;
272272
273273 // Adjust the bottom left side of the new tree.
274− if (concated[1].table.length > 0) {
275− b.table[0] = concated[1];
276− b.lengths[0] = length(concated[1]);
274+ if (appended[1].table.length > 0) {
275+ b.table[0] = appended[1];
276+ b.lengths[0] = length(appended[1]);
277277 for (var i = 1, len = length(b.table[0]); i < b.lengths.length; i++) {
278278 len += length(b.table[i]);
279279 b.lengths[i] = len;
@@ -475,7 +475,7 @@ Elm.Native.Array.make = function(elm) {
475475 Elm.Native.Array.values = {
476476 empty:empty,
477477 toList:toList,
478− concat:F2(concat),
478+ append:F2(append),
479479 push:F2(push),
480480 slice:F3(slice),
481481 get:F2(get),