Skip to content

Commit 6c57fc9

Browse files
committed
Restrict to a closed row in runSTArray
1 parent 766b7f4 commit 6c57fc9

File tree

2 files changed

+41
-26
lines changed

2 files changed

+41
-26
lines changed

src/Data/Array.purs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ import Prelude
115115
import Control.Alt ((<|>))
116116
import Control.Alternative (class Alternative)
117117
import Control.Lazy (class Lazy, defer)
118-
import Control.Monad.Eff (Eff, runPure)
118+
import Control.Monad.Eff (Eff)
119119
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM2)
120120
import Control.Monad.ST (ST)
121121

@@ -554,21 +554,20 @@ group' = group <<< sort
554554
-- | specified equivalence relation to detemine equality.
555555
groupBy :: forall a. (a -> a -> Boolean) -> Array a -> Array (NonEmpty Array a)
556556
groupBy op xs =
557-
runPure do
558-
runGroupedSTArray do
559-
result <- emptySTArray
560-
iter <- iterator (xs !! _)
561-
iterate iter \x -> do
562-
sub <- emptySTArray
563-
pushSTArray result (x :| sub)
564-
pushWhile (op x) iter sub
565-
pure result
557+
runGroupedSTArray do
558+
result <- emptySTArray
559+
iter <- iterator (xs !! _)
560+
iterate iter \x -> do
561+
sub <- emptySTArray
562+
pushSTArray result (x :| sub)
563+
pushWhile (op x) iter sub
564+
pure result
566565
where
567566
runGroupedSTArray
568-
:: forall b r
569-
. (forall h. Eff (st :: ST h | r) (STArray h (NonEmpty (STArray h) b)))
570-
-> Eff r (Array (NonEmpty Array b))
571-
runGroupedSTArray a = map unwrap (runSTArray' (map Grouped a))
567+
:: forall b
568+
. (forall h. Eff (st :: ST h) (STArray h (NonEmpty (STArray h) b)))
569+
-> Array (NonEmpty Array b)
570+
runGroupedSTArray a = unwrap (runSTArray' (map Grouped a))
572571

573572
newtype Grouped a arr = Grouped (arr (NonEmpty arr a))
574573
derive instance newtypeGrouped :: Newtype (Grouped a arr) _

src/Data/Array/ST.purs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module Data.Array.ST
1818
) where
1919

2020
import Prelude
21-
import Control.Monad.Eff (Eff)
21+
import Control.Monad.Eff (Eff, Pure, runPure)
2222
import Control.Monad.ST (ST)
2323
import Data.Maybe (Maybe(..))
2424
import Data.Newtype (class Newtype, unwrap)
@@ -43,25 +43,41 @@ derive instance newtypeId :: Newtype (Id a f) _
4343
-- | Freeze a mutable array, creating an immutable array. Use this function as you would use
4444
-- | `runST` to freeze a mutable reference.
4545
-- |
46-
-- | The rank-2 type prevents the reference from escaping the scope of `runSTArray`.
46+
-- | The rank-2 type prevents the reference from escaping the scope of `runSTArray'`,
47+
-- | and the closed row on the `Eff` computation prevents the reference from
48+
-- | escaping into other parts of your program via native effects such as `setTimeout`.
49+
-- |
50+
-- | You can also return an immutable copy of an `STArray` from an `ST` computation
51+
-- | by using `freeze` combined with `runST`. However, when possible, you should
52+
-- | prefer this function, because it is `O(1)`. By contrast, `freeze` must copy the
53+
-- | underlying array and is therefore `O(n)`.
4754
runSTArray
48-
:: forall a r
49-
. (forall h. Eff (st :: ST h | r) (STArray h a))
50-
-> Eff r (Array a)
51-
runSTArray a = map unwrap (runSTArray' (map Id a))
55+
:: forall a
56+
. (forall h. Eff (st :: ST h) (STArray h a))
57+
-> Array a
58+
runSTArray a = unwrap (runSTArray' (map Id a))
5259

5360
-- | Freeze all mutable arrays in some structure, creating a version of the
5461
-- | same structure where all mutable arrays are replaced with immutable
5562
-- | arrays. Use this function as you would use `runST` to freeze a mutable
5663
-- | reference.
5764
-- |
58-
-- | The rank-2 type prevents the reference from escaping the scope of `runSTArray'`.
65+
-- | The rank-2 type prevents the reference from escaping the scope of `runSTArray'`,
66+
-- | and the closed row on the `Eff` computation prevents the reference from
67+
-- | escaping into other parts of your program via native effects such as `setTimeout`.
68+
-- |
69+
-- | You can also return an immutable copy of an `STArray` from an `ST` computation
70+
-- | by using `freeze` combined with `runST`. However, when possible, you should
71+
-- | prefer this function, because it is `O(1)`. By contrast, `freeze` must copy the
72+
-- | underlying array and is therefore `O(n)`.
5973
runSTArray'
60-
:: forall f r
61-
. (forall h. Eff (st :: ST h | r) (f (STArray h)))
62-
-> Eff r (f Array)
63-
runSTArray' =
64-
unsafeCoerce
74+
:: forall f
75+
. (forall h. Eff (st :: ST h) (f (STArray h)))
76+
-> f Array
77+
runSTArray' x = runPure (go x)
78+
where
79+
go :: (forall h. Eff (st :: ST h) (f (STArray h))) -> Pure (f Array)
80+
go = unsafeCoerce
6581

6682
-- | Create an empty mutable array.
6783
foreign import emptySTArray :: forall a h r. Eff (st :: ST h | r) (STArray h a)

0 commit comments

Comments
 (0)