Skip to content

Commit f77c3c9

Browse files
committed
More tests, STArray fixes for negative indices
1 parent 33501e7 commit f77c3c9

File tree

10 files changed

+265
-71
lines changed

10 files changed

+265
-71
lines changed

bower.json

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
],
1818
"dependencies": {
1919
"purescript-foldable-traversable": "~0.4.0",
20-
"purescript-functions": "~0.1.0",
2120
"purescript-st": "~0.1.0"
2221
},
2322
"devDependencies": {

docs/Data.Array.md

+6
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@ sortBy :: forall a. (a -> a -> Ordering) -> Array a -> Array a
307307
Sort the elements of an array in increasing order, where elements are compared using
308308
the specified partial ordering, creating a new array.
309309

310+
#### `slice`
311+
312+
``` purescript
313+
slice :: forall a. Int -> Int -> Array a -> Array a
314+
```
315+
310316
#### `take`
311317

312318
``` purescript

src/Data/Array.purs

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ module Data.Array
4646
, sort
4747
, sortBy
4848

49+
, slice
4950
, take
5051
, takeWhile
5152
, drop
@@ -325,7 +326,7 @@ foreign import sortImpl :: forall a. (a -> a -> Int) -> Array a -> Array a
325326
-- Subarrays -------------------------------------------------------------------
326327
--------------------------------------------------------------------------------
327328

328-
-- | Extract a subarray by a start index and length.
329+
-- | Extract a subarray by a start and end index.
329330
foreign import slice :: forall a. Int -> Int -> Array a -> Array a
330331

331332
-- | Keep only a number of elements from the start of an array, creating a new

src/Data/Array/ST.js

+37-19
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,61 @@ exports.emptySTArray = function () {
1111
return [];
1212
};
1313

14-
exports.peekSTArrayImpl = function (just, nothing, arr, i) {
15-
return function () {
16-
return i < arr.length ? just(arr[i]) : nothing;
14+
exports.peekSTArrayImpl = function (just) {
15+
return function (nothing) {
16+
return function (xs) {
17+
return function (i) {
18+
return function () {
19+
return i >= 0 && i < xs.length ? just(xs[i]) : nothing;
20+
};
21+
};
22+
};
1723
};
1824
};
1925

20-
exports.pokeSTArrayImpl = function (arr, i, a) {
21-
return function () {
22-
var ret = i < arr.length;
23-
if (ret) arr[i] = a;
24-
return ret;
26+
exports.pokeSTArray = function (xs) {
27+
return function (i) {
28+
return function (a) {
29+
return function () {
30+
var ret = i >= 0 && i < xs.length;
31+
if (ret) xs[i] = a;
32+
return ret;
33+
};
34+
};
2535
};
2636
};
2737

28-
exports.pushAllSTArrayImpl = function (arr, as) {
29-
return function () {
30-
return arr.push.apply(arr, as);
38+
exports.pushAllSTArray = function (xs) {
39+
return function (as) {
40+
return function () {
41+
return xs.push.apply(xs, as);
42+
};
3143
};
3244
};
3345

34-
exports.spliceSTArrayImpl = function (arr, i, howMany, bs) {
35-
return function () {
36-
return arr.splice.apply(arr, [i, howMany].concat(bs));
46+
exports.spliceSTArray = function (xs) {
47+
return function (i) {
48+
return function (howMany) {
49+
return function (bs) {
50+
return function () {
51+
return xs.splice.apply(xs, [i, howMany].concat(bs));
52+
};
53+
};
54+
};
3755
};
3856
};
3957

40-
exports.copyImpl = function (arr) {
58+
exports.copyImpl = function (xs) {
4159
return function () {
42-
return arr.slice();
60+
return xs.slice();
4361
};
4462
};
4563

46-
exports.toAssocArray = function (arr) {
64+
exports.toAssocArray = function (xs) {
4765
return function () {
48-
var n = arr.length;
66+
var n = xs.length;
4967
var as = new Array(n);
50-
for (var i = 0; i < n; i++) as[i] = { value: arr[i], index: i };
68+
for (var i = 0; i < n; i++) as[i] = { value: xs[i], index: i };
5169
return as;
5270
};
5371
};

src/Data/Array/ST.purs

+17-40
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ module Data.Array.ST
1818

1919
import Control.Monad.Eff (Eff())
2020
import Control.Monad.ST (ST())
21-
import Data.Function (Fn2(), runFn2, Fn3(), runFn3, Fn4(), runFn4)
2221
import Data.Maybe (Maybe(..))
2322

2423
-- | A reference to a mutable array.
@@ -42,56 +41,34 @@ foreign import runSTArray :: forall a r. (forall h. Eff (st :: ST h | r) (STArra
4241
-- | Create an empty mutable array.
4342
foreign import emptySTArray :: forall a h r. Eff (st :: ST h | r) (STArray h a)
4443

45-
foreign import peekSTArrayImpl :: forall a h e r. Fn4 (a -> r)
46-
r
47-
(STArray h a)
48-
Int
49-
(Eff (st :: ST h | e) r)
44+
-- | Create a mutable copy of an immutable array.
45+
thaw :: forall a h r. Array a -> Eff (st :: ST h | r) (STArray h a)
46+
thaw = copyImpl
5047

51-
-- | Read the value at the specified index in a mutable array.
52-
peekSTArray :: forall a h r. STArray h a -> Int -> Eff (st :: ST h | r) (Maybe a)
53-
peekSTArray = runFn4 peekSTArrayImpl Just Nothing
48+
-- | Create an immutable copy of a mutable array.
49+
freeze :: forall a h r. STArray h a -> Eff (st :: ST h | r) (Array a)
50+
freeze = copyImpl
5451

55-
-- | Change the value at the specified index in a mutable array.
56-
pokeSTArray :: forall a h r. STArray h a -> Int -> a -> Eff (st :: ST h | r) Boolean
57-
pokeSTArray = runFn3 pokeSTArrayImpl
52+
foreign import copyImpl :: forall a b h r. a -> Eff (st :: ST h | r) b
5853

59-
foreign import pokeSTArrayImpl :: forall a h e. Fn3 (STArray h a)
60-
Int
61-
a
62-
(Eff (st :: ST h | e) Boolean)
54+
-- | Read the value at the specified index in a mutable array.
55+
peekSTArray :: forall a h r. STArray h a -> Int -> Eff (st :: ST h | r) (Maybe a)
56+
peekSTArray = peekSTArrayImpl Just Nothing
6357

64-
-- | Append the values in an immutable array to the end of a mutable array.
65-
pushAllSTArray :: forall a h r. STArray h a -> Array a -> Eff (st :: ST h | r) Int
66-
pushAllSTArray = runFn2 pushAllSTArrayImpl
58+
foreign import peekSTArrayImpl :: forall a h e r. (a -> r) -> r -> (STArray h a) -> Int -> (Eff (st :: ST h | e) r)
6759

68-
foreign import pushAllSTArrayImpl :: forall a h r. Fn2 (STArray h a)
69-
(Array a)
70-
(Eff (st :: ST h | r) Int)
60+
-- | Change the value at the specified index in a mutable array.
61+
foreign import pokeSTArray :: forall a h r. STArray h a -> Int -> a -> Eff (st :: ST h | r) Boolean
7162

7263
-- | Append an element to the end of a mutable array.
7364
pushSTArray :: forall a h r. STArray h a -> a -> Eff (st :: ST h | r) Int
7465
pushSTArray arr a = pushAllSTArray arr [a]
7566

76-
-- | Remove and/or insert elements from/into a mutable array at the specified index.
77-
spliceSTArray :: forall a h r. STArray h a -> Int -> Int -> Array a -> Eff (st :: ST h | r) (Array a)
78-
spliceSTArray = runFn4 spliceSTArrayImpl
79-
80-
foreign import spliceSTArrayImpl :: forall a h r. Fn4 (STArray h a)
81-
Int
82-
Int
83-
(Array a)
84-
(Eff (st :: ST h | r) (Array a))
85-
86-
-- | Create an immutable copy of a mutable array.
87-
freeze :: forall a h r. STArray h a -> Eff (st :: ST h | r) (Array a)
88-
freeze = copyImpl
89-
90-
-- | Create a mutable copy of an immutable array.
91-
thaw :: forall a h r. Array a -> Eff (st :: ST h | r) (STArray h a)
92-
thaw = copyImpl
67+
-- | Append the values in an immutable array to the end of a mutable array.
68+
foreign import pushAllSTArray :: forall a h r. STArray h a -> Array a -> Eff (st :: ST h | r) Int
9369

94-
foreign import copyImpl :: forall a b h r. a -> Eff (st :: ST h | r) b
70+
-- | Remove and/or insert elements from/into a mutable array at the specified index.
71+
foreign import spliceSTArray :: forall a h r. STArray h a -> Int -> Int -> Array a -> Eff (st :: ST h | r) (Array a)
9572

9673
-- | Create an immutable copy of a mutable array, where each element
9774
-- | is labelled with its index in the original array.

src/Data/Array/Unsafe.purs

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
module Data.Array.Unsafe where
77

8-
import Data.Maybe.Unsafe (fromJust)
9-
import qualified Data.Array as A
8+
import Data.Array (length, slice)
109

1110
-- | Find the element of an array at the specified index.
1211
-- |
@@ -23,16 +22,16 @@ head xs = unsafeIndex xs 0
2322
-- |
2423
-- | Running time: `O(n)`, where `n` is the length of the array.
2524
tail :: forall a. Array a -> Array a
26-
tail xs = (fromJust (A.uncons xs)).tail
25+
tail xs = slice 1 (length xs) xs
2726

2827
-- | Get the last element of a non-empty array.
2928
-- |
3029
-- | Running time: `O(1)`.
3130
last :: forall a. Array a -> a
32-
last xs = unsafeIndex xs (A.length xs - one)
31+
last xs = unsafeIndex xs (length xs - 1)
3332

3433
-- | Get all but the last element of a non-empty array.
3534
-- |
3635
-- | Running time: `O(n)`, where `n` is the length of the array.
3736
init :: forall a. Array a -> Array a
38-
init = fromJust <<< A.init
37+
init xs = slice 0 (length xs - 1) xs

test/Test/Data/Array.purs

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
module Test.Data.Array (testArray) where
22

3-
import Console (log, print)
3+
import Console (log)
44
import Data.Array
5-
import Data.Maybe (Maybe(..))
5+
import Data.Maybe (Maybe(..), isNothing)
6+
import Data.Maybe.Unsafe (fromJust)
67
import Test.Assert (assert)
78

89
testArray = do
@@ -22,7 +23,12 @@ testArray = do
2223
assert $ replicate 0 "foo" == []
2324
assert $ replicate (-1) "foo" == []
2425

25-
-- replicateM
26+
log "replicateM should perform the monadic action the correct number of times"
27+
assert $ replicateM 3 (Just 1) == Just [1, 1, 1]
28+
assert $ replicateM 1 (Just 1) == Just [1]
29+
assert $ replicateM 0 (Just 1) == Just []
30+
assert $ replicateM (-1) (Just 1) == Just []
31+
2632
-- some
2733
-- many
2834

@@ -70,7 +76,16 @@ testArray = do
7076
log "init should return Nothing for an empty array"
7177
assert $ init nil == Nothing
7278

73-
-- uncons
79+
log "uncons should return nothing when used on an empty array"
80+
assert $ isNothing (uncons nil)
81+
82+
log "uncons should split an array into a head and tail record when there is at least one item"
83+
let u1 = uncons [1]
84+
assert $ (fromJust u1).head == 1
85+
assert $ (fromJust u1).tail == []
86+
let u2 = uncons [1, 2, 3]
87+
assert $ (fromJust u2).head == 1
88+
assert $ (fromJust u2).tail == [2, 3]
7489

7590
log "(!!) should return Just x when the index is within the bounds of the array"
7691
assert $ [1, 2, 3] !! 0 == (Just 1)

0 commit comments

Comments
 (0)