on ab5baf6 help sign in
elk/libraries/Array.elm
206 lines 5.8 kB history raw
1module Array where
3{-| A library for immutable arrays. The elements in an array must have the same
4type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast
5reads, updates, and concatenation.
7If you use more then one map or zip function on an array, consider turning it
8into a list before operating on it, and then turning it back into an array.
10# Basics
11@docs empty, length, get, getMaybe, getSafe
13# Putting Arrays Together
14@docs fill, fromList, concat, set, updates, push
16# Taking Arrays Apart
17@docs toList, toIndexedList, indices, slice
19# Mapping, folding, zipping
20@docs map, indexedMap, foldl, foldr, zip, zipWith
21-}
23import Native.Array
24import Basics (..)
25import Maybe (..)
26import List
28data Array a = Array
30{-| Fills an array with a given length and a default element.
32 fill 3 5 == fromList [5,5,5]
33-}
34fill : Int -> a -> Array a
35fill len e = fromList <| List.map (always e) [1..len]
37-- TODO: make this a native function.
38{-| Create an array from a list. -}
39fromList : [a] -> Array a
40fromList = List.foldl (Native.Array.push) Native.Array.empty
42{-| Create a list of elements from an array.
44 toList (fromList [3,5,8]) == [3,5,8]
45-}
46toList : Array a -> [a]
47toList = Native.Array.toList
49{-| Create a list of the possible indices of an array.
51 indices (fromList [3,5,8] == [0,1,2])
52-}
53indices : Array a -> [Int]
54indices a = [0..Native.Array.length a - 1]
56-- TODO: make this a native function.
57{-| Create a list of tuples (Index, Element) from an array.
59 toIndexedList (fromList [3,5,8]) == [(0,3), (1,5), (2,8)]
60-}
61toIndexedList : Array a -> [(Int, a)]
62toIndexedList a = List.zip (indices a) (Native.Array.toList a)
64{-| Apply a function on every element in an array.
66 map (\x -> x*x) (fromList [1,2,3]) == fromList [1,4,9]
67-}
68map : (a -> b) -> Array a -> Array b
69map = Native.Array.map
71{-| Apply a function on every element with its index as first argument.
73 indexedMap (*) (fromList [5,5,5]) == fromList [0,5,10]
74-}
75indexedMap : (Int -> a -> b) -> Array a -> Array b
76indexedMap = Native.Array.indexedMap
78{-| Reduce an array from the left.
80 foldl (+) 0 (fill 3 5) == 15
81-}
82foldl : (a -> b -> b) -> b -> Array a -> b
83foldl = Native.Array.foldl
85{-| Reduce an array from the right.
87 foldr (::) [] (fromList [1,2,3]) == [3,2,1]
88-}
89foldr : (a -> b -> b) -> b -> Array a -> b
90foldr = Native.Array.foldr
92{-| Zip the elements of two arrays via a tuple into a new array. If one array is
93longer, the extra elements are dropped.
95 zip (fromList [1,2,3,4]) (fromList [0,0,0]) = fromList [(1,0), (2,0), (3,0)]
96-}
97zip : Array a -> Array b -> Array (a,b)
98zip = zipWith (,)
100{-| Zips the elements of two arrays via a function into a new array. If one array
101is longer, the extra elements are dropped.
103 zipWith (+) (fill 3 5) (fill 5 8) == fill 3 13
104-}
105zipWith : (a -> b -> c) -> Array a -> Array b -> Array c
106zipWith f a b =
107 fromList <| List.zipWith f (Native.Array.toList a) (Native.Array.toList b)
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{-| Return the element at the index. Breaks, if index is out of range. If the
124array length is unkown, use safeGet oder getWithDefault.
126 get 2 (A.fromList [3,2,1]) == 1
127-}
128get : Int -> Array a -> a
129get = Native.Array.get
131{-| Return Just the element at the index or Nothing if the index is out of range.
133 getMaybe 2 (A.fromList [3,2,1]) == Just 2
134 getMaybe 5 (A.fromList [3,2,1]) == Nothing
135-}
136<<<<<<< HEAD
137getMaybe : Int -> Array a -> Maybe a
138getMaybe i array = if Native.Array.length array > i
139 then Just (Native.Array.get i array)
140 else Nothing
141=======
142safeGet : Int -> Array a -> Maybe a
143safeGet i array =
144 if i < Native.Array.length array
145 then Just (Native.Array.get i array)
146 else Nothing
147>>>>>>> dev
149{-| Get the element at the index. If the index is out of range, the given default
150element is returned.
152 getSafe 0 2 (A.fromList [3,2,1]) == 1
153 getSafe 0 5 (A.fromList [3,2,1]) == 0
154-}
155<<<<<<< HEAD
156getSafe : a -> Int -> Array a -> a
157getSafe default i array = if Native.Array.length array > i
158 then Native.Array.get i array else default
159=======
160getWithDefault : a -> Int -> Array a -> a
161getWithDefault default i array =
162 if i < Native.Array.length array
163 then Native.Array.get i array
164 else default
165>>>>>>> dev
167{-| Set the element at the index. Returns the updated array, or if the index is
168out of range, the unaltered array.
170 set 1 7 (fromList [1,2,3]) == fromList [1,7,3]
171-}
172set : Int -> a -> Array a -> Array a
173set = Native.Array.set
175{-| Update an array with a a list tuples, wherein the first Int is the index.
177 updates [(1,7),(2,8)] (fill 3 1) == fromList [1,7,8]
178-}
179updates : [(Int, a)] -> Array a -> Array a
180updates us array = List.foldl (uncurry Native.Array.set) array us
182{-| Slice an array given a range. The selection is inclusive, so the last
183element in the selection will also be in the new array. This may change in the
184future.
185You can select from the end by giving a negative Int.
187 slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
188 slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
189 slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
190-}
191slice : Int -> Int -> Array a -> Array a
192slice = Native.Array.slice
194{-| Return the length of an array.
196 length (fromList [1,2,3]) == 3
197-}
198length : Array a -> Int
199length = Native.Array.length
201{-| Concat two arrays to a new one.
203 concat (fill 3 1) (fill 4 2) == fromList [1,1,1,2,2,2,2]
204-}
205concat : Array a -> Array a -> Array a
206concat = Native.Array.concat