Skip to content

Commit 816d8d4

Browse files
authored
Merge pull request #152 from Dretch/run-st-array
Add runSTArray for efficiently constructing arrays using ST.
2 parents f80754d + f6604b3 commit 816d8d4

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/Data/Array/ST.purs

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

2627
import Prelude
2728

29+
import Control.Monad.ST as ST
2830
import Control.Monad.ST (ST, kind Region)
2931
import Data.Maybe (Maybe(..))
3032
import Unsafe.Coerce (unsafeCoerce)
@@ -41,6 +43,13 @@ foreign import data STArray :: Region -> Type -> Type
4143
-- | An element and its index.
4244
type Assoc a = { value :: a, index :: Int }
4345

46+
-- | A safe way to create and work with a mutable array before returning an
47+
-- | immutable array for later perusal. This function avoids copying the array
48+
-- | before returning it - it uses unsafeFreeze internally, but this wrapper is
49+
-- | a safe interface to that function.
50+
run :: forall a. (forall h. ST h (STArray h a)) -> Array a
51+
run st = ST.run (st >>= unsafeFreeze)
52+
4453
-- | Perform an effect requiring a mutable array on a copy of an immutable array,
4554
-- | safely returning the result as an immutable array.
4655
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 "run should produce an immutable array by running a constructor operation"
22+
23+
assert $ STA.run (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)