File tree Expand file tree Collapse file tree 2 files changed +54
-5
lines changed Expand file tree Collapse file tree 2 files changed +54
-5
lines changed Original file line number Diff line number Diff line change @@ -444,10 +444,33 @@ instance Foldable Array where
444444 {-# INLINE product #-}
445445#endif
446446
447+ newtype STA a = STA { _runSTA :: forall s . MutableArray # s a -> ST s (Array a )}
448+
449+ runSTA :: Int -> STA a -> Array a
450+ runSTA ! sz = \ (STA m) -> runST $ newArray_ sz >>= \ ar -> m (marray# ar)
451+ {-# INLINE runSTA #-}
452+
453+ newArray_ :: Int -> ST s (MutableArray s a )
454+ newArray_ ! n = newArray n badTraverseValue
455+
456+ badTraverseValue :: a
457+ badTraverseValue = die " traverse" " bad indexing"
458+ {-# NOINLINE badTraverseValue #-}
459+
447460instance Traversable Array where
448- traverse f a =
449- fromListN (sizeofArray a)
450- <$> traverse (f . indexArray a) [0 .. sizeofArray a - 1 ]
461+ traverse f = \ ! ary ->
462+ let
463+ ! len = sizeofArray ary
464+ go ! i
465+ | i == len = pure $ STA $ \ mary -> unsafeFreezeArray (MutableArray mary)
466+ | (# x # ) <- indexArray## ary i
467+ = liftA2 (\ b (STA m) -> STA $ \ mary ->
468+ writeArray (MutableArray mary) i b >> m mary)
469+ (f x) (go (i + 1 ))
470+ in if len == 0
471+ then pure emptyArray
472+ else runSTA len <$> go 0
473+ {-# INLINE traverse #-}
451474
452475#if MIN_VERSION_base(4,7,0)
453476instance Exts. IsList (Array a ) where
Original file line number Diff line number Diff line change @@ -525,9 +525,35 @@ instance Foldable SmallArray where
525525 {-# INLINE product #-}
526526#endif
527527
528+ newtype STA a = STA { _runSTA :: forall s . SmallMutableArray # s a -> ST s (SmallArray a )}
529+
530+ runSTA :: Int -> STA a -> SmallArray a
531+ runSTA ! sz = \ (STA m) -> runST $ newSmallArray_ sz >>=
532+ \ (SmallMutableArray ar# ) -> m ar#
533+ {-# INLINE runSTA #-}
534+
535+ newSmallArray_ :: Int -> ST s (SmallMutableArray s a )
536+ newSmallArray_ ! n = newSmallArray n badTraverseValue
537+
538+ badTraverseValue :: a
539+ badTraverseValue = die " traverse" " bad indexing"
540+ {-# NOINLINE badTraverseValue #-}
541+
528542instance Traversable SmallArray where
529- traverse f sa = fromListN l <$> traverse (f . indexSmallArray sa) [0 .. l- 1 ]
530- where l = length sa
543+ traverse f = \ ! ary ->
544+ let
545+ ! len = sizeofSmallArray ary
546+ go ! i
547+ | i == len
548+ = pure $ STA $ \ mary -> unsafeFreezeSmallArray (SmallMutableArray mary)
549+ | (# x # ) <- indexSmallArray## ary i
550+ = liftA2 (\ b (STA m) -> STA $ \ mary ->
551+ writeSmallArray (SmallMutableArray mary) i b >> m mary)
552+ (f x) (go (i + 1 ))
553+ in if len == 0
554+ then pure emptySmallArray
555+ else runSTA len <$> go 0
556+ {-# INLINE traverse #-}
531557
532558instance Functor SmallArray where
533559 fmap f sa = createSmallArray (length sa) (die " fmap" " impossible" ) $ \ smb ->
You can’t perform that action at this time.
0 commit comments