Skip to content

Commit 79995c7

Browse files
committed
Add runSTArray for efficiently constructing arrays using ST.
Haskell has this already. Also add a test for withArray.
1 parent b709a3c commit 79995c7

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/Data/Array/ST.purs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
module Data.Array.ST
66
( STArray(..)
77
, Assoc
8+
, runSTArray
89
, withArray
910
, empty
1011
, peek
@@ -25,7 +26,7 @@ module Data.Array.ST
2526

2627
import Prelude
2728

28-
import Control.Monad.ST (ST, kind Region)
29+
import Control.Monad.ST (ST, kind Region, run)
2930
import Data.Maybe (Maybe(..))
3031
import Unsafe.Coerce (unsafeCoerce)
3132

@@ -41,6 +42,13 @@ foreign import data STArray :: Region -> Type -> Type
4142
-- | An element and its index.
4243
type Assoc a = { value :: a, index :: Int }
4344

45+
-- | A safe way to create and work with a mutable array before returning an
46+
-- | immutable array for later perusal. This function avoids copying the array
47+
-- | before returning it - it uses unsafeFreeze internally, but this wrapper is
48+
-- | a safe interface to that function.
49+
runSTArray :: forall a. (forall h. ST h (STArray h a)) -> Array a
50+
runSTArray st = run (st >>= unsafeFreeze)
51+
4452
-- | Perform an effect requiring a mutable array on a copy of an immutable array,
4553
-- | safely returning the result as an immutable array.
4654
withArray

test/Test/Data/Array/ST.purs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Prelude
44

55
import Control.Monad.ST (ST)
66
import Control.Monad.ST as ST
7-
import Data.Array.ST (STArray)
7+
import Data.Array.ST (STArray, withArray)
88
import Data.Array.ST as STA
99
import Data.Foldable (all)
1010
import Data.Maybe (Maybe(..), isNothing)
@@ -18,6 +18,20 @@ run act = ST.run (act >>= STA.unsafeFreeze)
1818
testArrayST :: Effect Unit
1919
testArrayST = do
2020

21+
log "runSTArray should produce an immutable array by running a constructor operation"
22+
23+
assert $ STA.runSTArray (do
24+
arr <- STA.empty
25+
void $ STA.push 1 arr
26+
void $ STA.push 2 arr
27+
pure arr) == [1, 2]
28+
29+
log "withArray should run an operation on a copy of an array"
30+
31+
let original = [1, 2, 3]
32+
assert $ ST.run (withArray (STA.push 42) original) == [1, 2, 3, 42]
33+
assert $ original == [1, 2, 3]
34+
2135
log "empty should produce an empty array"
2236

2337
assert $ run STA.empty == nil

0 commit comments

Comments
 (0)