Skip to content

Commit

Permalink
Merge pull request #157 from 8084/add-pop-shift-unshift
Browse files Browse the repository at this point in the history
added: pop, shift, unshift, unshiftAll to Data.Array.ST
  • Loading branch information
garyb authored Apr 27, 2019
2 parents 83c2148 + 8882669 commit 1bca4c0
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 1 deletion.
28 changes: 28 additions & 0 deletions src/Data/Array/ST.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ exports.poke = function (i) {
};
};

exports.popImpl = function (just) {
return function (nothing) {
return function (xs) {
return function () {
return xs.length > 0 ? just(xs.pop()) : nothing;
};
};
};
};

exports.pushAll = function (as) {
return function (xs) {
return function () {
Expand All @@ -36,6 +46,24 @@ exports.pushAll = function (as) {
};
};

exports.shiftImpl = function (just) {
return function (nothing) {
return function (xs) {
return function () {
return xs.length > 0 ? just(xs.shift()) : nothing;
};
};
};
};

exports.unshiftAll = function (as) {
return function (xs) {
return function () {
return xs.unshift.apply(xs, as);
};
};
};

exports.splice = function (i) {
return function (howMany) {
return function (bs) {
Expand Down
41 changes: 40 additions & 1 deletion src/Data/Array/ST.purs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ module Data.Array.ST
, empty
, peek
, poke
, push
, modify
, pop
, push
, pushAll
, shift
, unshift
, unshiftAll
, splice
, sort
, sortBy
Expand Down Expand Up @@ -83,6 +87,17 @@ thaw = copyImpl
sort :: forall a h. Ord a => STArray h a -> ST h (STArray h a)
sort = sortBy compare

-- | Remove the first element from an array and return that element.
shift :: forall h a. STArray h a -> ST h (Maybe a)
shift = shiftImpl Just Nothing

foreign import shiftImpl
:: forall h a
. (forall b. b -> Maybe b)
-> (forall b. Maybe b)
-> STArray h a
-> ST h (Maybe a)

-- | Sort a mutable array in place using a comparison function.
sortBy
:: forall a h
Expand Down Expand Up @@ -136,6 +151,17 @@ foreign import peekImpl
-- | Change the value at the specified index in a mutable array.
foreign import poke :: forall h a. Int -> a -> STArray h a -> ST h Boolean

-- | Remove the last element from an array and return that element.
pop :: forall h a. STArray h a -> ST h (Maybe a)
pop = popImpl Just Nothing

foreign import popImpl
:: forall h a
. (forall b. b -> Maybe b)
-> (forall b. Maybe b)
-> STArray h a
-> ST h (Maybe a)

-- | Append an element to the end of a mutable array. Returns the new length of
-- | the array.
push :: forall h a. a -> STArray h a -> ST h Int
Expand All @@ -149,6 +175,19 @@ foreign import pushAll
-> STArray h a
-> ST h Int

-- | Append an element to the front of a mutable array. Returns the new length of
-- | the array.
unshift :: forall h a. a -> STArray h a -> ST h Int
unshift a = unshiftAll [a]

-- | Append the values in an immutable array to the front of a mutable array.
-- | Returns the new length of the mutable array.
foreign import unshiftAll
:: forall h a
. Array a
-> STArray h a
-> ST h Int

-- | Mutate the element at the specified index using the supplied function.
modify :: forall h a. Int -> (a -> a) -> STArray h a -> ST h Boolean
modify i f xs = do
Expand Down
75 changes: 75 additions & 0 deletions test/Test/Data/Array/ST.purs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ testArrayST = do

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

log "pop should remove elements from an STArray"

assert $ STA.run (do
arr <- STA.thaw [1, 2, 3]
void $ STA.pop arr
pure arr) == [1, 2]

log "pop should return the last element of an STArray"

assert $ ST.run (do
arr <- STA.thaw [1, 2, 3]
STA.pop arr) == Just 3

log "pop should return Nothing when given an empty array"

assert $ isNothing $ ST.run (do
arr <- STA.empty
STA.pop arr)

log "push should append a value to the end of the array"

assert $ STA.run (do
Expand Down Expand Up @@ -145,6 +164,62 @@ testArrayST = do
void $ STA.poke 1 2 arr
pure arr) == [1]

log "shift should remove elements from an STArray"

assert $ STA.run (do
arr <- STA.thaw [1, 2, 3]
void $ STA.shift arr
pure arr) == [2, 3]

log "shift should return the first element of an STArray"

assert $ ST.run (do
arr <- STA.thaw [1, 2, 3]
STA.shift arr) == Just 1

log "shift should return Nothing when given an empty array"

assert $ isNothing $ ST.run (do
arr <- STA.empty
STA.shift arr)

log "unshift should append a value to the front of the array"

assert $ STA.run (do
arr <- STA.empty
void $ STA.unshift 1 arr
void $ STA.unshift 2 arr
pure arr) == [2, 1]

assert $ STA.run (do
arr <- STA.thaw [1, 2, 3]
void $ STA.unshift 4 arr
pure arr) == [4, 1, 2, 3]

log "unshift should return the new length of the array"

assert $ ST.run (do
arr <- STA.thaw [unit, unit, unit]
STA.unshift unit arr) == 4

log "unshiftAll should append multiple values to the front of the array"

assert $ STA.run (do
arr <- STA.empty
void $ STA.unshiftAll [1, 2] arr
pure arr) == [1, 2]

assert $ STA.run (do
arr <- STA.thaw [1, 2, 3]
void $ STA.unshiftAll [4, 5, 6] arr
pure arr) == [4, 5, 6, 1, 2, 3]

log "unshiftAll should return the new length of the array"

assert $ ST.run (do
arr <- STA.thaw [unit, unit, unit]
STA.unshiftAll [unit, unit] arr) == 5

log "sort should reorder a list into ascending order based on the result of compare"
assert $ STA.run (
STA.sort =<< STA.unsafeThaw [1, 3, 2, 5, 6, 4]
Expand Down

0 comments on commit 1bca4c0

Please sign in to comment.