Skip to content

Add runSTArray for efficiently constructing arrays using ST. #152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Data/Array/ST.purs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
module Data.Array.ST
( STArray(..)
, Assoc
, run
, withArray
, empty
, peek
Expand All @@ -25,6 +26,7 @@ module Data.Array.ST

import Prelude

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

-- | A safe way to create and work with a mutable array before returning an
-- | immutable array for later perusal. This function avoids copying the array
-- | before returning it - it uses unsafeFreeze internally, but this wrapper is
-- | a safe interface to that function.
run :: forall a. (forall h. ST h (STArray h a)) -> Array a
run st = ST.run (st >>= unsafeFreeze)

-- | Perform an effect requiring a mutable array on a copy of an immutable array,
-- | safely returning the result as an immutable array.
withArray
Expand Down
16 changes: 15 additions & 1 deletion test/Test/Data/Array/ST.purs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Prelude

import Control.Monad.ST (ST)
import Control.Monad.ST as ST
import Data.Array.ST (STArray)
import Data.Array.ST (STArray, withArray)
import Data.Array.ST as STA
import Data.Foldable (all)
import Data.Maybe (Maybe(..), isNothing)
Expand All @@ -18,6 +18,20 @@ run act = ST.run (act >>= STA.unsafeFreeze)
testArrayST :: Effect Unit
testArrayST = do

log "run should produce an immutable array by running a constructor operation"

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

log "withArray should run an operation on a copy of an array"

let original = [1, 2, 3]
assert $ ST.run (withArray (STA.push 42) original) == [1, 2, 3, 42]
assert $ original == [1, 2, 3]

log "empty should produce an empty array"

assert $ run STA.empty == nil
Expand Down