@@ -20,7 +20,7 @@ module Data.Primitive.Array (
2020 Array (.. ), MutableArray (.. ),
2121
2222 newArray , readArray , writeArray , indexArray , indexArrayM ,
23- freezeArray , thawArray , runArray , runArrays , runArraysHetOf , runArraysHetOfThen ,
23+ freezeArray , thawArray , runArray , runArrays , runArraysOf , runArraysHetOf ,
2424 unsafeFreezeArray , unsafeThawArray , sameMutableArray ,
2525 copyArray , copyMutableArray ,
2626 cloneArray , cloneMutableArray ,
@@ -29,7 +29,6 @@ module Data.Primitive.Array (
2929 unsafeTraverseArray
3030) where
3131
32- import Data.Functor.Compose
3332import Control.Monad.Primitive
3433
3534import GHC.Base ( Int (.. ) )
@@ -805,14 +804,46 @@ instance (Typeable s, Typeable a) => Data (MutableArray s a) where
805804-- | Create any number of arrays of the same type within an arbitrary
806805-- 'Traversable' context. This will often be useful with traversables
807806-- like @(c,)@, @'Either' e@, @'Compose' (c,) ('Either' e)@, and
808- -- @'Compose' ('Either' e) (c,)@. For a more general version, see
809- -- 'runArraysHetOf'.
807+ -- @'Compose' ('Either' e) (c,)@. To use an arbitrary traversal
808+ -- function, see 'runArraysOf'. To create arrays of varying types,
809+ -- see 'runArraysHetOf'.
810810runArrays
811811 :: Traversable t
812812 => (forall s . ST s (t (MutableArray s a )))
813813 -> t (Array a )
814814runArrays m = runST $ m >>= traverse unsafeFreezeArray
815815
816+ -- | Just like 'runArrays', but takes an arbitrary (potentially
817+ -- type-changing) traversal function instead of requiring a 'Traversable'
818+ -- constraint. To produce arrays of varying types, use 'runArraysHetOf'.
819+ runArraysOf
820+ :: (forall s1 s2 .
821+ (MutableArray s1 a -> ST s2 (Array a )) -> t (MutableArray s1 a ) -> ST s2 (u (Array a )))
822+ -> (forall s . ST s (t (MutableArray s a )))
823+ -> u (Array a )
824+ runArraysOf trav m = runST $ m >>= trav unsafeFreezeArray
825+
826+ {-
827+ I initially thought we'd need a function like
828+
829+ runArraysOfThen
830+ :: (forall s1 s2.
831+ (MutableArray s1 a -> Compose (ST s2) q r) -> t (MutableArray s1 a) -> Compose (ST s2) q (u r))
832+ -> (Array a -> q r)
833+ -> (forall s. ST s (t (MutableArray s a)))
834+ -> q (u r)
835+
836+ to allow users to traverse over the generated arrays. But because 'runArraysOf'
837+ allows the traversal function to know that it is producing values of type
838+ @Array a@, one could just write
839+
840+ runArraysOfThen trav post m = getConst $
841+ runArraysOf (\f -> coerce . getCompose . (trav (Compose . fmap post . f))) m
842+
843+ Perhaps such a function *should* be added for convenience, but it's
844+ clearly not necessary.
845+ -}
846+
816847-- | Create arbitrarily many arrays that may have different types.
817848-- For a simpler but less general version, see 'runArrays'.
818849--
@@ -848,27 +879,27 @@ runArrays m = runST $ m >>= traverse unsafeFreezeArray
848879--
849880-- traversePair :: Applicative h => (forall x. f x -> h (g x)) -> Pair ab f -> h (Pair ab g)
850881-- traversePair f (Pair (xs, ys)) = liftA2 (\x y -> Pair (x,y)) (f xs) (f ys)
882+ --
883+ -- ==== Produce a container of arrays and traverse over them
884+ --
885+ -- @
886+ -- runArraysHetOfThen
887+ -- :: (forall s1 s2.
888+ -- ((forall x. MutableArray s1 x -> Compose (ST s2) q (r x)) -> t (MutableArray s1) -> Compose (ST s2) q (u r)))
889+ -- -- ^ A rank-2 traversal
890+ -- -> (forall x. Array x -> q (r x))
891+ -- -- ^ A function to traverse over the container of 'Array's
892+ -- -> (forall s. ST s (t (MutableArray s)))
893+ -- -- ^ An 'ST' action producing a rank-2 container of 'MutableArray's.
894+ -- -> q (u r)
895+ -- runArraysHetOfThen trav post m = getConst $
896+ -- runArraysHetOf (\f -> coerce . getCompose . trav (Compose . fmap post . f)) m
851897-- @
852898runArraysHetOf
853- :: (forall h f g .
854- (Applicative h => (forall x . f x -> h ( g x )) -> t f -> h (u g )))
899+ :: (forall s1 s2 .
900+ ((forall x . MutableArray s1 x -> ST s2 ( Array x )) -> t ( MutableArray s1 ) -> ST s2 (u Array )))
855901 -- ^ A rank-2 traversal
856902 -> (forall s . ST s (t (MutableArray s )))
857903 -- ^ An 'ST' action producing a rank-2 container of 'MutableArray's.
858904 -> u Array
859905runArraysHetOf trav m = runST $ m >>= trav unsafeFreezeArray
860-
861- -- | Similar to 'runArraysHetOf', but takes a function to traverse over the
862- -- generated 'Array's as it freezes them.
863- runArraysHetOfThen
864- :: Applicative q
865- => (forall h f g .
866- (Applicative h => (forall x . f x -> h (g x )) -> t f -> h (u g )))
867- -- ^ A rank-2 traversal
868- -> (forall x . Array x -> q (r x ))
869- -- ^ A function to traverse over the container of 'Array's
870- -> (forall s . ST s (t (MutableArray s )))
871- -- ^ An 'ST' action producing a rank-2 container of 'MutableArray's.
872- -> q (u r )
873- runArraysHetOfThen trav post m =
874- runST $ m >>= getCompose . trav (Compose . fmap post . unsafeFreezeArray)
0 commit comments