on 467ff50 help sign in
elk/libraries/Array.elm
189 lines 5.3 kB history raw
1module Array where
3{-| A library for fast immutable arrays. The elements in an array must have the
4same type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast
5reads, updates, and appends.
7# Creating Arrays
8@docs empty, repeat, initialize, fromList
10# Basics
11@docs length, push, append
13# Get and Set
14@docs get, getSafe, getUnsafe, set
16# Taking Arrays Apart
17@docs toList, toIndexedList, slice
19# Mapping and Folding
20@docs map, indexedMap, foldl, foldr
21-}
23import Native.Array
24import Basics (..)
25import Maybe (..)
26import List
28data Array a = Array
30{-| Initialize an array. `initialize n f` creates an array of length `n` with
31the element at index `i` initialized to the result of `(f i)`.
33 initialize 4 id == fromList [0,1,2,3]
34 initialize 4 (\n -> n*n) == fromList [0,1,4,9]
35 initialize 4 (always 0) == fromList [0,0,0,0]
36-}
37initialize : Int -> (Int -> a) -> Array a
38initialize = Native.Array.initialize
40{-| Creates an array with a given length, filled with a default element.
42 repeat 5 0 == fromList [0,0,0,0,0]
43 repeat 3 "cat" == fromList ["cat","cat","cat"]
45Notice that `repeat 3 x` is the same as `initialize 3 (always x)`.
46-}
47repeat : Int -> a -> Array a
48repeat n e = initialize n (always e)
50{-| Create an array from a list. -}
51fromList : [a] -> Array a
52fromList = Native.Array.fromList
54{-| Create a list of elements from an array.
56 toList (fromList [3,5,8]) == [3,5,8]
57-}
58toList : Array a -> [a]
59toList = Native.Array.toList
61-- TODO: make this a native function.
62{-| Create an indexed list from an array. Each element of the array will be
63paired with its index.
65 toIndexedList (fromList ["cat","dog"]) == [(0,"cat"), (1,"dog")]
66-}
67toIndexedList : Array a -> [(Int, a)]
68toIndexedList array =
69 List.zip [ 0 .. Native.Array.length array - 1 ] (Native.Array.toList array)
71{-| Apply a function on every element in an array.
73 map sqrt (fromList [1,4,9]) == fromList [1,2,3]
74-}
75map : (a -> b) -> Array a -> Array b
76map = Native.Array.map
78{-| Apply a function on every element with its index as first argument.
80 indexedMap (*) (fromList [5,5,5]) == fromList [0,5,10]
81-}
82indexedMap : (Int -> a -> b) -> Array a -> Array b
83indexedMap = Native.Array.indexedMap
85{-| Reduce an array from the left. Read `foldl` as “fold from the left”.
87 foldl (::) [] (fromList [1,2,3]) == [3,2,1]
88-}
89foldl : (a -> b -> b) -> b -> Array a -> b
90foldl = Native.Array.foldl
92{-| Reduce an array from the right. Read `foldr` as “fold from the right”.
94 foldr (+) 0 (repeat 3 5) == 15
95-}
96foldr : (a -> b -> b) -> b -> Array a -> b
97foldr = Native.Array.foldr
99{-| Keep only elements that satisfy the predicate:
101 filter isEven (fromList [1..6]) == (fromList [2,4,6])
102-}
103filter : (a -> Bool) -> Array a -> Array a
104filter isOkay arr =
105 let update x xs = if isOkay x then Native.Array.push x xs else xs
106 in
107 Native.Array.foldl update Native.Array.empty arr
109{-| Return an empty array.
111 length empty == 0
112-}
113empty : Array a
114empty = Native.Array.empty
116{-| Push an element to the end of an array.
118 push 3 (fromList [1,2]) == fromList [1,2,3]
119-}
120push : a -> Array a -> Array a
121push = Native.Array.push
123{-| Get the element at a particular index.
125 getUnsafe 2 (A.fromList [3,2,1]) == 1
127Warning: this function will result in a runtime error if the index is not found,
128so it is best to use `get` or `getSafe` unless you are very confident the index
129will be found.
130-}
131getUnsafe : Int -> Array a -> a
132getUnsafe = Native.Array.get
134{-| Return Just the element at the index or Nothing if the index is out of range.
136 get 2 (fromList [3,2,1]) == Just 2
137 get 5 (fromList [3,2,1]) == Nothing
138 get -1 (fromList [3,2,1]) == Nothing
139-}
140get : Int -> Array a -> Maybe a
141get i array =
142 if 0 <= i && i < Native.Array.length array
143 then Just (Native.Array.get i array)
144 else Nothing
146{-| Get the element at the index. If the index is out of range, the given default
147element is returned.
149 getSafe 0 2 (fromList [3,2,1]) == 1
150 getSafe 0 5 (fromList [3,2,1]) == 0
151-}
152getSafe : a -> Int -> Array a -> a
153getSafe default i array =
154 if 0 <= i && i < Native.Array.length array
155 then Native.Array.get i array
156 else default
158{-| Set the element at a particular index. Returns an updated array.
159If the index is out of range, the array is unaltered.
161 set 1 7 (fromList [1,2,3]) == fromList [1,7,3]
162-}
163set : Int -> a -> Array a -> Array a
164set = Native.Array.set
166{-| Slice an array given a range. The selection is inclusive, so the last
167element in the selection will also be in the new array. This may change in the
168future. You can select from the end by giving a negative Int.
170 slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
171 slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
172 slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
173-}
174slice : Int -> Int -> Array a -> Array a
175slice = Native.Array.slice
177{-| Return the length of an array.
179 length (fromList [1,2,3]) == 3
180-}
181length : Array a -> Int
182length = Native.Array.length
184{-| Append two arrays to a new one.
186 append (array 2 42) (array 3 81) == fromList [42,42,81,81,81]
187-}
188append : Array a -> Array a -> Array a
189append = Native.Array.append