Skip to content

Commit 8690471

Browse files
committed
Updates for parity with purescript-lists, more tests
1 parent 1aeaf39 commit 8690471

File tree

4 files changed

+190
-86
lines changed

4 files changed

+190
-86
lines changed

docs/Data.Array.md

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ snoc :: forall a. Array a -> a -> Array a
107107

108108
Append an element to the end of an array, creating a new array.
109109

110+
#### `insert`
111+
112+
``` purescript
113+
insert :: forall a. (Ord a) => a -> Array a -> Array a
114+
```
115+
116+
Insert an element into a sorted array.
117+
118+
#### `insertBy`
119+
120+
``` purescript
121+
insertBy :: forall a. (a -> a -> Ordering) -> a -> Array a -> Array a
122+
```
123+
124+
Insert an element into a sorted array, using the specified function to
125+
determine the ordering of elements.
126+
110127
#### `head`
111128

112129
``` purescript
@@ -200,34 +217,48 @@ Find the last index for which a predicate holds.
200217
#### `insertAt`
201218

202219
``` purescript
203-
insertAt :: forall a. Int -> a -> Array a -> Array a
220+
insertAt :: forall a. Int -> a -> Array a -> Maybe (Array a)
204221
```
205222

206-
Insert an element at the specified index, creating a new array.
223+
Insert an element at the specified index, creating a new array, or
224+
returning `Nothing` if the index is out of bounds.
207225

208226
#### `deleteAt`
209227

210228
``` purescript
211-
deleteAt :: forall a. Int -> Int -> Array a -> Array a
229+
deleteAt :: forall a. Int -> Array a -> Maybe (Array a)
212230
```
213231

214-
Delete the element at the specified index, creating a new array.
232+
Delete the element at the specified index, creating a new array, or
233+
returning `Nothing` if the index is out of bounds.
215234

216235
#### `updateAt`
217236

218237
``` purescript
219-
updateAt :: forall a. Int -> a -> Array a -> Array a
238+
updateAt :: forall a. Int -> a -> Array a -> Maybe (Array a)
220239
```
221240

222-
Change the element at the specified index, creating a new array.
241+
Change the element at the specified index, creating a new array, or
242+
returning `Nothing` if the index is out of bounds.
223243

224244
#### `modifyAt`
225245

226246
``` purescript
227-
modifyAt :: forall a. Int -> (a -> a) -> Array a -> Array a
247+
modifyAt :: forall a. Int -> (a -> a) -> Array a -> Maybe (Array a)
248+
```
249+
250+
Apply a function to the element at the specified index, creating a new
251+
array, or returning `Nothing` if the index is out of bounds.
252+
253+
#### `alterAt`
254+
255+
``` purescript
256+
alterAt :: forall a. Int -> (a -> Maybe a) -> Array a -> Maybe (Array a)
228257
```
229258

230-
Apply a function to the element at the specified index, creating a new array.
259+
Update or delete the element at the specified index by applying a
260+
function to the current value, returning a new array or `Nothing` if the
261+
index is out-of-bounds.
231262

232263
#### `reverse`
233264

src/Data/Array.js

Lines changed: 31 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -106,35 +106,45 @@ exports.findLastIndexImpl = function (just) {
106106
};
107107
};
108108

109-
exports.insertAt = function (i) {
110-
return function (a) {
111-
return function (l) {
112-
if (i < 0 || i >= l.length) return l;
113-
var l1 = l.slice();
114-
l1.splice(i, 0, a);
115-
return l1;
109+
exports._insertAt = function (just) {
110+
return function (nothing) {
111+
return function (i) {
112+
return function (a) {
113+
return function (l) {
114+
if (i < 0 || i > l.length) return nothing;
115+
var l1 = l.slice();
116+
l1.splice(i, 0, a);
117+
return just(l1);
118+
};
119+
};
116120
};
117121
};
118122
};
119123

120-
exports.deleteAt = function (i) {
121-
return function (n) {
122-
return function (l) {
123-
if (i < 0 || i >= l.length) return l;
124-
var l1 = l.slice();
125-
l1.splice(i, n);
126-
return l1;
124+
exports._deleteAt = function (just) {
125+
return function (nothing) {
126+
return function (i) {
127+
return function (l) {
128+
if (i < 0 || i >= l.length) return nothing;
129+
var l1 = l.slice();
130+
l1.splice(i, 1);
131+
return just(l1);
132+
};
127133
};
128134
};
129135
};
130136

131-
exports.updateAt = function (i) {
132-
return function (a) {
133-
return function (l) {
134-
if (i < 0 || i >= l.length) return l;
135-
var l1 = l.slice();
136-
l1[i] = a;
137-
return l1;
137+
exports._updateAt = function (just) {
138+
return function (nothing) {
139+
return function (i) {
140+
return function (a) {
141+
return function (l) {
142+
if (i < 0 || i >= l.length) return nothing;
143+
var l1 = l.slice();
144+
l1[i] = a;
145+
return just(l1);
146+
};
147+
};
138148
};
139149
};
140150
};
@@ -211,29 +221,3 @@ exports.zipWith = function (f) {
211221
};
212222
};
213223
};
214-
215-
//------------------------------------------------------------------------------
216-
// Folding ---------------------------------------------------------------------
217-
//------------------------------------------------------------------------------
218-
219-
exports.foldrArray = function (f) {
220-
return function (init) {
221-
return function (xs) {
222-
/* jshint maxparams: 2 */
223-
return xs.reduceRight(function (acc, x) {
224-
return f(x)(acc);
225-
}, init);
226-
};
227-
};
228-
};
229-
230-
exports.foldlArray = function (f) {
231-
return function (init) {
232-
return function (xs) {
233-
/* jshint maxparams: 2 */
234-
return xs.reduce(function (acc, x) {
235-
return f(acc)(x);
236-
}, init);
237-
};
238-
};
239-
};

src/Data/Array.purs

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module Data.Array
1818

1919
, (:), cons
2020
, snoc
21+
, insert
22+
, insertBy
2123

2224
, head
2325
, last
@@ -34,6 +36,7 @@ module Data.Array
3436
, deleteAt
3537
, updateAt
3638
, modifyAt
39+
, alterAt
3740

3841
, reverse
3942
, concat
@@ -58,6 +61,8 @@ module Data.Array
5861

5962
, nub
6063
, nubBy
64+
-- , union
65+
-- , unionBy
6166
, delete
6267
, deleteBy
6368

@@ -85,6 +90,8 @@ import Data.Monoid (Monoid, mempty)
8590
import Data.Traversable (sequence)
8691
import Data.Tuple (Tuple(..))
8792

93+
import qualified Data.Maybe.Unsafe as U
94+
8895
--------------------------------------------------------------------------------
8996
-- Array creation --------------------------------------------------------------
9097
--------------------------------------------------------------------------------
@@ -162,6 +169,17 @@ infixr 6 :
162169
-- | Append an element to the end of an array, creating a new array.
163170
foreign import snoc :: forall a. Array a -> a -> Array a
164171

172+
-- | Insert an element into a sorted array.
173+
insert :: forall a. (Ord a) => a -> Array a -> Array a
174+
insert = insertBy compare
175+
176+
-- | Insert an element into a sorted array, using the specified function to
177+
-- | determine the ordering of elements.
178+
insertBy :: forall a. (a -> a -> Ordering) -> a -> Array a -> Array a
179+
insertBy cmp x ys =
180+
let index = maybe 0 (+ 1) (findLastIndex (\y -> cmp x y == GT) ys)
181+
in U.fromJust (insertAt index x ys)
182+
165183
--------------------------------------------------------------------------------
166184
-- Non-indexed reads -----------------------------------------------------------
167185
--------------------------------------------------------------------------------
@@ -236,8 +254,8 @@ findIndex = findIndexImpl Just Nothing
236254
foreign import findIndexImpl :: forall a. (forall b. b -> Maybe b)
237255
-> (forall b. Maybe b)
238256
-> (a -> Boolean)
239-
-> (Array a)
240-
-> (Maybe Int)
257+
-> Array a
258+
-> Maybe Int
241259

242260
-- | Find the last index for which a predicate holds.
243261
findLastIndex :: forall a. (a -> Boolean) -> Array a -> Maybe Int
@@ -246,21 +264,60 @@ findLastIndex = findLastIndexImpl Just Nothing
246264
foreign import findLastIndexImpl :: forall a. (forall b. b -> Maybe b)
247265
-> (forall b. Maybe b)
248266
-> (a -> Boolean)
249-
-> (Array a)
250-
-> (Maybe Int)
267+
-> Array a
268+
-> Maybe Int
251269

252-
-- | Insert an element at the specified index, creating a new array.
253-
foreign import insertAt :: forall a. Int -> a -> Array a -> Array a
270+
-- | Insert an element at the specified index, creating a new array, or
271+
-- | returning `Nothing` if the index is out of bounds.
272+
insertAt :: forall a. Int -> a -> Array a -> Maybe (Array a)
273+
insertAt = _insertAt Just Nothing
254274

255-
-- | Delete the element at the specified index, creating a new array.
256-
foreign import deleteAt :: forall a. Int -> Int -> Array a -> Array a
275+
foreign import _insertAt :: forall a. (forall b. b -> Maybe b)
276+
-> (forall b. Maybe b)
277+
-> Int
278+
-> a
279+
-> Array a
280+
-> Maybe (Array a)
257281

258-
-- | Change the element at the specified index, creating a new array.
259-
foreign import updateAt :: forall a. Int -> a -> Array a -> Array a
282+
-- | Delete the element at the specified index, creating a new array, or
283+
-- | returning `Nothing` if the index is out of bounds.
284+
deleteAt :: forall a. Int -> Array a -> Maybe (Array a)
285+
deleteAt = _deleteAt Just Nothing
260286

261-
-- | Apply a function to the element at the specified index, creating a new array.
262-
modifyAt :: forall a. Int -> (a -> a) -> Array a -> Array a
263-
modifyAt i f xs = maybe xs (\x -> updateAt i (f x) xs) (xs !! i)
287+
foreign import _deleteAt :: forall a. (forall b. b -> Maybe b)
288+
-> (forall b. Maybe b)
289+
-> Int
290+
-> Array a
291+
-> Maybe (Array a)
292+
293+
-- | Change the element at the specified index, creating a new array, or
294+
-- | returning `Nothing` if the index is out of bounds.
295+
updateAt :: forall a. Int -> a -> Array a -> Maybe (Array a)
296+
updateAt = _updateAt Just Nothing
297+
298+
foreign import _updateAt :: forall a. (forall b. b -> Maybe b)
299+
-> (forall b. Maybe b)
300+
-> Int
301+
-> a
302+
-> Array a
303+
-> Maybe (Array a)
304+
305+
-- | Apply a function to the element at the specified index, creating a new
306+
-- | array, or returning `Nothing` if the index is out of bounds.
307+
modifyAt :: forall a. Int -> (a -> a) -> Array a -> Maybe (Array a)
308+
modifyAt i f xs = maybe Nothing go (xs !! i)
309+
where
310+
go x = updateAt i (f x) xs
311+
312+
-- | Update or delete the element at the specified index by applying a
313+
-- | function to the current value, returning a new array or `Nothing` if the
314+
-- | index is out-of-bounds.
315+
alterAt :: forall a. Int -> (a -> Maybe a) -> Array a -> Maybe (Array a)
316+
alterAt i f xs = maybe Nothing go (xs !! i)
317+
where
318+
go x = case f x of
319+
Nothing -> deleteAt i xs
320+
Just x' -> updateAt i x' xs
264321

265322
--------------------------------------------------------------------------------
266323
-- Transformations -------------------------------------------------------------
@@ -419,7 +476,7 @@ delete = deleteBy eq
419476
-- | new array.
420477
deleteBy :: forall a. (a -> a -> Boolean) -> a -> Array a -> Array a
421478
deleteBy _ _ [] = []
422-
deleteBy eq x ys = maybe ys (\i -> deleteAt i one ys) (findIndex (eq x) ys)
479+
deleteBy eq x ys = maybe ys (\i -> U.fromJust $ deleteAt i ys) (findIndex (eq x) ys)
423480

424481
infix 5 \\
425482

@@ -477,7 +534,3 @@ unzip = uncons' (\_ -> Tuple [] []) \(Tuple a b) ts -> case unzip ts of
477534
-- | Perform a fold using a monadic step function.
478535
foldM :: forall m a b. (Monad m) => (a -> b -> m a) -> a -> Array b -> m a
479536
foldM f a = uncons' (\_ -> return a) (\b bs -> f a b >>= \a' -> foldM f a' bs)
480-
481-
foreign import foldrArray :: forall a b. (a -> b -> b) -> b -> Array a -> b
482-
483-
foreign import foldlArray :: forall a b. (b -> a -> b) -> b -> Array a -> b

0 commit comments

Comments
 (0)