Skip to content

Commit 1bca4c0

Browse files
authored
Merge pull request #157 from 8084/add-pop-shift-unshift
added: pop, shift, unshift, unshiftAll to Data.Array.ST
2 parents 83c2148 + 8882669 commit 1bca4c0

File tree

3 files changed

+143
-1
lines changed

3 files changed

+143
-1
lines changed

src/Data/Array/ST.js

+28
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ exports.poke = function (i) {
2828
};
2929
};
3030

31+
exports.popImpl = function (just) {
32+
return function (nothing) {
33+
return function (xs) {
34+
return function () {
35+
return xs.length > 0 ? just(xs.pop()) : nothing;
36+
};
37+
};
38+
};
39+
};
40+
3141
exports.pushAll = function (as) {
3242
return function (xs) {
3343
return function () {
@@ -36,6 +46,24 @@ exports.pushAll = function (as) {
3646
};
3747
};
3848

49+
exports.shiftImpl = function (just) {
50+
return function (nothing) {
51+
return function (xs) {
52+
return function () {
53+
return xs.length > 0 ? just(xs.shift()) : nothing;
54+
};
55+
};
56+
};
57+
};
58+
59+
exports.unshiftAll = function (as) {
60+
return function (xs) {
61+
return function () {
62+
return xs.unshift.apply(xs, as);
63+
};
64+
};
65+
};
66+
3967
exports.splice = function (i) {
4068
return function (howMany) {
4169
return function (bs) {

src/Data/Array/ST.purs

+40-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ module Data.Array.ST
1010
, empty
1111
, peek
1212
, poke
13-
, push
1413
, modify
14+
, pop
15+
, push
1516
, pushAll
17+
, shift
18+
, unshift
19+
, unshiftAll
1620
, splice
1721
, sort
1822
, sortBy
@@ -83,6 +87,17 @@ thaw = copyImpl
8387
sort :: forall a h. Ord a => STArray h a -> ST h (STArray h a)
8488
sort = sortBy compare
8589

90+
-- | Remove the first element from an array and return that element.
91+
shift :: forall h a. STArray h a -> ST h (Maybe a)
92+
shift = shiftImpl Just Nothing
93+
94+
foreign import shiftImpl
95+
:: forall h a
96+
. (forall b. b -> Maybe b)
97+
-> (forall b. Maybe b)
98+
-> STArray h a
99+
-> ST h (Maybe a)
100+
86101
-- | Sort a mutable array in place using a comparison function.
87102
sortBy
88103
:: forall a h
@@ -136,6 +151,17 @@ foreign import peekImpl
136151
-- | Change the value at the specified index in a mutable array.
137152
foreign import poke :: forall h a. Int -> a -> STArray h a -> ST h Boolean
138153

154+
-- | Remove the last element from an array and return that element.
155+
pop :: forall h a. STArray h a -> ST h (Maybe a)
156+
pop = popImpl Just Nothing
157+
158+
foreign import popImpl
159+
:: forall h a
160+
. (forall b. b -> Maybe b)
161+
-> (forall b. Maybe b)
162+
-> STArray h a
163+
-> ST h (Maybe a)
164+
139165
-- | Append an element to the end of a mutable array. Returns the new length of
140166
-- | the array.
141167
push :: forall h a. a -> STArray h a -> ST h Int
@@ -149,6 +175,19 @@ foreign import pushAll
149175
-> STArray h a
150176
-> ST h Int
151177

178+
-- | Append an element to the front of a mutable array. Returns the new length of
179+
-- | the array.
180+
unshift :: forall h a. a -> STArray h a -> ST h Int
181+
unshift a = unshiftAll [a]
182+
183+
-- | Append the values in an immutable array to the front of a mutable array.
184+
-- | Returns the new length of the mutable array.
185+
foreign import unshiftAll
186+
:: forall h a
187+
. Array a
188+
-> STArray h a
189+
-> ST h Int
190+
152191
-- | Mutate the element at the specified index using the supplied function.
153192
modify :: forall h a. Int -> (a -> a) -> STArray h a -> ST h Boolean
154193
modify i f xs = do

test/Test/Data/Array/ST.purs

+75
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,25 @@ testArrayST = do
4646

4747
assert $ STA.run (STA.unsafeThaw [1, 2, 3]) == [1, 2, 3]
4848

49+
log "pop should remove elements from an STArray"
50+
51+
assert $ STA.run (do
52+
arr <- STA.thaw [1, 2, 3]
53+
void $ STA.pop arr
54+
pure arr) == [1, 2]
55+
56+
log "pop should return the last element of an STArray"
57+
58+
assert $ ST.run (do
59+
arr <- STA.thaw [1, 2, 3]
60+
STA.pop arr) == Just 3
61+
62+
log "pop should return Nothing when given an empty array"
63+
64+
assert $ isNothing $ ST.run (do
65+
arr <- STA.empty
66+
STA.pop arr)
67+
4968
log "push should append a value to the end of the array"
5069

5170
assert $ STA.run (do
@@ -145,6 +164,62 @@ testArrayST = do
145164
void $ STA.poke 1 2 arr
146165
pure arr) == [1]
147166

167+
log "shift should remove elements from an STArray"
168+
169+
assert $ STA.run (do
170+
arr <- STA.thaw [1, 2, 3]
171+
void $ STA.shift arr
172+
pure arr) == [2, 3]
173+
174+
log "shift should return the first element of an STArray"
175+
176+
assert $ ST.run (do
177+
arr <- STA.thaw [1, 2, 3]
178+
STA.shift arr) == Just 1
179+
180+
log "shift should return Nothing when given an empty array"
181+
182+
assert $ isNothing $ ST.run (do
183+
arr <- STA.empty
184+
STA.shift arr)
185+
186+
log "unshift should append a value to the front of the array"
187+
188+
assert $ STA.run (do
189+
arr <- STA.empty
190+
void $ STA.unshift 1 arr
191+
void $ STA.unshift 2 arr
192+
pure arr) == [2, 1]
193+
194+
assert $ STA.run (do
195+
arr <- STA.thaw [1, 2, 3]
196+
void $ STA.unshift 4 arr
197+
pure arr) == [4, 1, 2, 3]
198+
199+
log "unshift should return the new length of the array"
200+
201+
assert $ ST.run (do
202+
arr <- STA.thaw [unit, unit, unit]
203+
STA.unshift unit arr) == 4
204+
205+
log "unshiftAll should append multiple values to the front of the array"
206+
207+
assert $ STA.run (do
208+
arr <- STA.empty
209+
void $ STA.unshiftAll [1, 2] arr
210+
pure arr) == [1, 2]
211+
212+
assert $ STA.run (do
213+
arr <- STA.thaw [1, 2, 3]
214+
void $ STA.unshiftAll [4, 5, 6] arr
215+
pure arr) == [4, 5, 6, 1, 2, 3]
216+
217+
log "unshiftAll should return the new length of the array"
218+
219+
assert $ ST.run (do
220+
arr <- STA.thaw [unit, unit, unit]
221+
STA.unshiftAll [unit, unit] arr) == 5
222+
148223
log "sort should reorder a list into ascending order based on the result of compare"
149224
assert $ STA.run (
150225
STA.sort =<< STA.unsafeThaw [1, 3, 2, 5, 6, 4]

0 commit comments

Comments
 (0)