@@ -86,7 +86,7 @@ import GHC.Exts (Int (..), SmallArray#, SmallMutableArray#,
86
86
cloneSmallMutableArray #, copySmallArray #,
87
87
copySmallMutableArray #, indexSmallArray #,
88
88
newSmallArray #, readSmallArray #,
89
- reallyUnsafePtrEquality #, sizeofSmallArray #,
89
+ reallyUnsafePtrEquality #, runRW #, sizeofSmallArray #,
90
90
sizeofSmallMutableArray #, tagToEnum #,
91
91
thawSmallArray #, unsafeCoerce #,
92
92
unsafeFreezeSmallArray #, unsafeThawSmallArray #,
@@ -205,13 +205,17 @@ new_ :: Int -> ST s (MArray s a)
205
205
new_ n = new n undefinedElem
206
206
207
207
singleton :: a -> Array a
208
- singleton x = runST (singletonM x)
208
+ singleton x = run (singletonMut x)
209
209
{-# INLINE singleton #-}
210
210
211
211
singletonM :: a -> ST s (Array a )
212
212
singletonM x = new 1 x >>= unsafeFreeze
213
213
{-# INLINE singletonM #-}
214
214
215
+ singletonMut :: a -> ST s (MArray s a )
216
+ singletonMut x = new 1 x
217
+ {-# INLINE singletonMut #-}
218
+
215
219
pair :: a -> a -> Array a
216
220
pair x y = run $ do
217
221
ary <- new 2 x
@@ -263,7 +267,17 @@ unsafeThaw ary
263
267
{-# INLINE unsafeThaw #-}
264
268
265
269
run :: (forall s . ST s (MArray s e )) -> Array e
266
- run act = runST $ act >>= unsafeFreeze
270
+ #if MIN_VERSION_base(4,9,0)
271
+ -- GHC can't unbox across the runRW# boundary, so we apply the Array constructor
272
+ -- on the outside.
273
+ run (ST act) =
274
+ case runRW# $ \ s ->
275
+ case act s of { (# s', MArray mary # ) ->
276
+ unsafeFreezeSmallArray# mary s' } of
277
+ (# _, ary # ) -> Array ary
278
+ #else
279
+ run act = runST (act >>= unsafeFreeze)
280
+ #endif
267
281
{-# INLINE run #-}
268
282
269
283
-- | Unsafely copy the elements of an array. Array bounds are not checked.
@@ -300,33 +314,37 @@ trim mary n = cloneM mary 0 n >>= unsafeFreeze
300
314
-- | /O(n)/ Insert an element at the given position in this array,
301
315
-- increasing its size by one.
302
316
insert :: Array e -> Int -> e -> Array e
303
- insert ary idx b = runST (insertM ary idx b)
317
+ insert ary idx b = run (insertMut ary idx b)
304
318
{-# INLINE insert #-}
305
319
306
320
-- | /O(n)/ Insert an element at the given position in this array,
307
321
-- increasing its size by one.
308
322
insertM :: Array e -> Int -> e -> ST s (Array e )
309
- insertM ary idx b =
323
+ insertM ary idx b = insertMut ary idx b >>= unsafeFreeze
324
+ {-# INLINE insertM #-}
325
+
326
+ insertMut :: Array e -> Int -> e -> ST s (MArray s e )
327
+ insertMut ary idx b =
310
328
CHECK_BOUNDS (" insertM" , count + 1 , idx)
311
329
do mary <- new (count+ 1 ) b
312
330
copy ary 0 mary 0 idx
313
331
copy ary idx mary (idx+ 1 ) (count- idx)
314
- unsafeFreeze mary
332
+ return mary
315
333
where ! count = length ary
316
- {-# INLINE insertM #-}
334
+ {-# INLINE insertMut #-}
317
335
318
336
-- | /O(n)/ Update the element at the given position in this array.
319
337
update :: Array e -> Int -> e -> Array e
320
- update ary idx b = runST (updateM ary idx b)
338
+ update ary idx b = run (updateM ary idx b)
321
339
{-# INLINE update #-}
322
340
323
341
-- | /O(n)/ Update the element at the given position in this array.
324
- updateM :: Array e -> Int -> e -> ST s (Array e )
342
+ updateM :: Array e -> Int -> e -> ST s (MArray s e )
325
343
updateM ary idx b =
326
344
CHECK_BOUNDS (" updateM" , count, idx)
327
345
do mary <- thaw ary 0 count
328
346
write mary idx b
329
- unsafeFreeze mary
347
+ return mary
330
348
where ! count = length ary
331
349
{-# INLINE updateM #-}
332
350
@@ -421,18 +439,18 @@ thaw !ary !_o@(I# o#) _n@(I# n#) =
421
439
-- | /O(n)/ Delete an element at the given position in this array,
422
440
-- decreasing its size by one.
423
441
delete :: Array e -> Int -> Array e
424
- delete ary idx = runST (deleteM ary idx)
442
+ delete ary idx = run (deleteM ary idx)
425
443
{-# INLINE delete #-}
426
444
427
445
-- | /O(n)/ Delete an element at the given position in this array,
428
446
-- decreasing its size by one.
429
- deleteM :: Array e -> Int -> ST s (Array e )
447
+ deleteM :: Array e -> Int -> ST s (MArray s e )
430
448
deleteM ary idx = do
431
449
CHECK_BOUNDS (" deleteM" , count, idx)
432
450
do mary <- new_ (count- 1 )
433
451
copy ary 0 mary 0 idx
434
452
copy ary (idx+ 1 ) mary idx (count- (idx+ 1 ))
435
- unsafeFreeze mary
453
+ return mary
436
454
where ! count = length ary
437
455
{-# INLINE deleteM #-}
438
456
@@ -442,9 +460,10 @@ map f = \ ary ->
442
460
in run $ do
443
461
mary <- new_ n
444
462
go ary mary 0 n
463
+ return mary
445
464
where
446
465
go ary mary i n
447
- | i >= n = return mary
466
+ | i >= n = return ()
448
467
| otherwise = do
449
468
x <- indexM ary i
450
469
write mary i $ f x
@@ -458,9 +477,10 @@ map' f = \ ary ->
458
477
in run $ do
459
478
mary <- new_ n
460
479
go ary mary 0 n
480
+ return mary
461
481
where
462
482
go ary mary i n
463
- | i >= n = return mary
483
+ | i >= n = return ()
464
484
| otherwise = do
465
485
x <- indexM ary i
466
486
write mary i $! f x
@@ -473,8 +493,9 @@ fromList n xs0 =
473
493
run $ do
474
494
mary <- new_ n
475
495
go xs0 mary 0
496
+ return mary
476
497
where
477
- go [] ! mary ! _ = return mary
498
+ go [] ! _ ! _ = return ()
478
499
go (x: xs) mary i = do write mary i x
479
500
go xs mary (i+ 1 )
480
501
0 commit comments