Skip to content

Commit 9d0f7a5

Browse files
committed
Expand, reduce
1 parent 26ce85b commit 9d0f7a5

File tree

1 file changed

+52
-21
lines changed

1 file changed

+52
-21
lines changed

Data/Primitive/Array.hs

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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
3332
import Control.Monad.Primitive
3433

3534
import 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'.
810810
runArrays
811811
:: Traversable t
812812
=> (forall s. ST s (t (MutableArray s a)))
813813
-> t (Array a)
814814
runArrays 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
-- @
852898
runArraysHetOf
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
859905
runArraysHetOf 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

Comments
 (0)