File tree Expand file tree Collapse file tree 2 files changed +24
-2
lines changed Expand file tree Collapse file tree 2 files changed +24
-2
lines changed Original file line number Diff line number Diff line change 55module Data.Array.ST
66 ( STArray (..)
77 , Assoc
8+ , runSTArray
89 , withArray
910 , empty
1011 , peek
@@ -25,7 +26,7 @@ module Data.Array.ST
2526
2627import Prelude
2728
28- import Control.Monad.ST (ST , kind Region )
29+ import Control.Monad.ST (ST , kind Region , run )
2930import Data.Maybe (Maybe (..))
3031import Unsafe.Coerce (unsafeCoerce )
3132
@@ -41,6 +42,13 @@ foreign import data STArray :: Region -> Type -> Type
4142-- | An element and its index.
4243type 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.
4654withArray
Original file line number Diff line number Diff line change @@ -4,7 +4,7 @@ import Prelude
44
55import Control.Monad.ST (ST )
66import Control.Monad.ST as ST
7- import Data.Array.ST (STArray )
7+ import Data.Array.ST (STArray , withArray )
88import Data.Array.ST as STA
99import Data.Foldable (all )
1010import Data.Maybe (Maybe (..), isNothing )
@@ -18,6 +18,20 @@ run act = ST.run (act >>= STA.unsafeFreeze)
1818testArrayST :: Effect Unit
1919testArrayST = 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
You can’t perform that action at this time.
0 commit comments