From d8d9f700e184867c124fc371315a1021c948d1f6 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 23 Oct 2020 20:02:15 -0700 Subject: [PATCH 1/4] Add unsafe versions of delete, insert, update, and modify --- src/Data/Array.js | 38 ++++++++++++++++++++++++++++++++++++++ src/Data/Array.purs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/Data/Array.js b/src/Data/Array.js index b9792582..93ab6bc8 100644 --- a/src/Data/Array.js +++ b/src/Data/Array.js @@ -148,6 +148,16 @@ exports._insertAt = function (just) { }; }; +exports._unsafeInsertAt = function (i) { + return function (a) { + return function (l) { + var l1 = l.slice(); + l1.splice(i, 0, a); + return l1; + }; + }; +}; + exports._deleteAt = function (just) { return function (nothing) { return function (i) { @@ -161,6 +171,14 @@ exports._deleteAt = function (just) { }; }; +exports._unsafeDeleteAt = function (i) { + return function (l) { + var l1 = l.slice(); + l1.splice(i, 1); + return l1; + }; +}; + exports._updateAt = function (just) { return function (nothing) { return function (i) { @@ -176,6 +194,26 @@ exports._updateAt = function (just) { }; }; +exports._unsafeUpdateAt = function (i) { + return function (a) { + return function (l) { + var l1 = l.slice(); + l1[i] = a; + return l1; + }; + }; +}; + +exports._unsafeModifyAt = function (i) { + return function (f) { + return function (l) { + var l1 = l.slice(); + l1[i] = f(l1[i]); + return l1; + }; + }; +}; + //------------------------------------------------------------------------------ // Transformations ------------------------------------------------------------- //------------------------------------------------------------------------------ diff --git a/src/Data/Array.purs b/src/Data/Array.purs index cb1dee91..1e3f356e 100644 --- a/src/Data/Array.purs +++ b/src/Data/Array.purs @@ -112,6 +112,10 @@ module Data.Array , foldRecM , unsafeIndex + , unsafeDeleteAt + , unsafeInsertAt + , unsafeUpdateAt + , unsafeModifyAt , module Exports ) where @@ -1145,3 +1149,43 @@ unsafeIndex :: forall a. Partial => Array a -> Int -> a unsafeIndex = unsafeIndexImpl foreign import unsafeIndexImpl :: forall a. Array a -> Int -> a + +-- | Delete the element at index `i` in an array +-- | +-- | ```purescript +-- | unsafePartial $ unsafeDeleteAt 1 ["a", "b", "c"] = ["a", "c"] +-- | ``` +unsafeDeleteAt :: forall a. Partial => Int -> Array a -> Array a +unsafeDeleteAt = unsafeDeleteAtImpl + +foreign import unsafeDeleteAtImpl :: forall a. Int -> Array a -> Array a + +-- | Insert the element at index `i` in an array +-- | +-- | ```purescript +-- | unsafePartial $ unsafeInsertAt 1 "b" ["a", "c"] = ["a", "b", "c"] +-- | ``` +unsafeInsertAt :: forall a. Partial => Int -> a -> Array a -> Array a +unsafeInsertAt = unsafeIndexImpl + +foreign import unsafeInsertAtImpl :: forall a. Int -> a -> Array a -> Array a + +-- | Overwrite the element at index `i` in an array +-- | +-- | ```purescript +-- | unsafePartial $ unsafeUpdateAt 1 "e" ["a", "b", "c"] = ["a", "e", "c"] +-- | ``` +unsafeUpdateAt :: forall a. Partial => Int -> a -> Array a -> Array a +unsafeUpdateAt = unsafeUpdateAtImpl + +foreign import unsafeUpdateAtImpl :: forall a. Int -> a -> Array a -> Array a + +-- | Overwrite the element at index `i` in an array +-- | +-- | ```purescript +-- | unsafePartial $ unsafeModifyAt 1 (\a -> a <> "e") ["a", "b", "c"] = ["a", "be", "c"] +-- | ``` +unsafeModifyAt :: forall a. Partial => Int -> (a -> a) -> Array a -> Array a +unsafeModifyAt = unsafeModifyAtImpl + +foreign import unsafeModifyAtImpl :: forall a. Int -> (a -> a) -> Array a -> Array a From f5c63e62cb0a3522c021ce667c94c6adfb2299d0 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 26 Nov 2020 21:21:35 -0800 Subject: [PATCH 2/4] Fix CI issue: referring to wrong function due to copy-past error --- src/Data/Array.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Array.purs b/src/Data/Array.purs index 1e3f356e..50540a2c 100644 --- a/src/Data/Array.purs +++ b/src/Data/Array.purs @@ -1166,7 +1166,7 @@ foreign import unsafeDeleteAtImpl :: forall a. Int -> Array a -> Array a -- | unsafePartial $ unsafeInsertAt 1 "b" ["a", "c"] = ["a", "b", "c"] -- | ``` unsafeInsertAt :: forall a. Partial => Int -> a -> Array a -> Array a -unsafeInsertAt = unsafeIndexImpl +unsafeInsertAt = unsafeInsertAtImpl foreign import unsafeInsertAtImpl :: forall a. Int -> a -> Array a -> Array a From e3f7ea7a61004a91872e508ae3c9d35f456f6d08 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 26 Nov 2020 21:21:51 -0800 Subject: [PATCH 3/4] Make FFI function names match PS function names --- src/Data/Array.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Array.js b/src/Data/Array.js index 93ab6bc8..742b063f 100644 --- a/src/Data/Array.js +++ b/src/Data/Array.js @@ -148,7 +148,7 @@ exports._insertAt = function (just) { }; }; -exports._unsafeInsertAt = function (i) { +exports.unsafeInsertAtImpl = function (i) { return function (a) { return function (l) { var l1 = l.slice(); @@ -171,7 +171,7 @@ exports._deleteAt = function (just) { }; }; -exports._unsafeDeleteAt = function (i) { +exports.unsafeDeleteAtImpl = function (i) { return function (l) { var l1 = l.slice(); l1.splice(i, 1); @@ -194,7 +194,7 @@ exports._updateAt = function (just) { }; }; -exports._unsafeUpdateAt = function (i) { +exports.unsafeUpdateAtImpl = function (i) { return function (a) { return function (l) { var l1 = l.slice(); @@ -204,7 +204,7 @@ exports._unsafeUpdateAt = function (i) { }; }; -exports._unsafeModifyAt = function (i) { +exports.unsafeModifyAtImpl = function (i) { return function (f) { return function (l) { var l1 = l.slice(); From d72a1f7ae451b1c5ea8760b900713f653c9cdca7 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 26 Nov 2020 21:21:59 -0800 Subject: [PATCH 4/4] Implement tests --- test/Test/Data/Array.purs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/Test/Data/Array.purs b/test/Test/Data/Array.purs index 39ff57a8..18ad1e4d 100644 --- a/test/Test/Data/Array.purs +++ b/test/Test/Data/Array.purs @@ -155,6 +155,10 @@ testArray = do log "insertAt should return Nothing if the index is out of A.range" assert $ (A.insertAt 2 1 nil) == Nothing + log "unsafeInsertAt should insert the element into the array at the given index if the index is valid" + assert $ (unsafePartial $ A.unsafeInsertAt 0 1 [0]) == [1, 0] + assert $ (unsafePartial $ A.unsafeInsertAt 1 1 [0]) == [0, 1] + log "deleteAt should remove an item at the specified index" assert $ (A.deleteAt 0 [1, 2, 3]) == Just [2, 3] assert $ (A.deleteAt 1 [1, 2, 3]) == Just [1, 3] @@ -162,6 +166,10 @@ testArray = do log "deleteAt should return Nothing if the index is out of A.range" assert $ (A.deleteAt 1 nil) == Nothing + log "unsafeDeleteAt should delete the element at the given index into the array" + assert $ (unsafePartial $ A.unsafeDeleteAt 0 [0, 1]) == [1] + assert $ (unsafePartial $ A.unsafeDeleteAt 1 [0, 1]) == [0] + log "updateAt should replace an item at the specified index" assert $ (A.updateAt 0 9 [1, 2, 3]) == Just [9, 2, 3] assert $ (A.updateAt 1 9 [1, 2, 3]) == Just [1, 9, 3] @@ -169,6 +177,10 @@ testArray = do log "updateAt should return Nothing if the index is out of A.range" assert $ (A.updateAt 1 9 nil) == Nothing + log "unsafeUpdateAt should update the element at the given index into the array" + assert $ (unsafePartial $ A.unsafeUpdateAt 0 2 [0, 1]) == [2, 1] + assert $ (unsafePartial $ A.unsafeUpdateAt 1 2 [0, 1]) == [0, 2] + log "modifyAt should update an item at the specified index" assert $ (A.modifyAt 0 (_ + 1) [1, 2, 3]) == Just [2, 2, 3] assert $ (A.modifyAt 1 (_ + 1) [1, 2, 3]) == Just [1, 3, 3] @@ -176,6 +188,10 @@ testArray = do log "modifyAt should return Nothing if the index is out of A.range" assert $ (A.modifyAt 1 (_ + 1) nil) == Nothing + log "unsafeModifyAt should update the element at the given index into the array" + assert $ (unsafePartial $ A.unsafeModifyAt 0 (_ + 1) [0, 1]) == [1, 1] + assert $ (unsafePartial $ A.unsafeModifyAt 1 (_ + 1) [0, 1]) == [0, 2] + log "alterAt should update an item at the specified index when the function returns Just" assert $ (A.alterAt 0 (Just <<< (_ + 1)) [1, 2, 3]) == Just [2, 2, 3] assert $ (A.alterAt 1 (Just <<< (_ + 1)) [1, 2, 3]) == Just [1, 3, 3]