11{-# LANGUAGE CPP, MagicHash, UnboxedTuples, DeriveDataTypeable, BangPatterns #-}
22{-# LANGUAGE RankNTypes #-}
33{-# LANGUAGE TypeFamilies #-}
4+ #if __GLASGOW_HASKELL__ >= 708
5+ {-# LANGUAGE PolyKinds #-}
6+ #endif
47
58-- |
69-- Module : Data.Primitive.Array
@@ -17,7 +20,7 @@ module Data.Primitive.Array (
1720 Array (.. ), MutableArray (.. ),
1821
1922 newArray , readArray , writeArray , indexArray , indexArrayM ,
20- freezeArray , thawArray , runArray ,
23+ freezeArray , thawArray , runArray , runArrays , runArraysHetOf ,
2124 unsafeFreezeArray , unsafeThawArray , sameMutableArray ,
2225 copyArray , copyMutableArray ,
2326 cloneArray , cloneMutableArray ,
@@ -341,7 +344,6 @@ emptyArray# _ = case emptyArray of Array ar -> ar
341344{-# NOINLINE emptyArray# #-}
342345#endif
343346
344-
345347die :: String -> String -> a
346348die fun problem = error $ " Data.Primitive.Array." ++ fun ++ " : " ++ problem
347349
@@ -798,3 +800,57 @@ instance (Typeable s, Typeable a) => Data (MutableArray s a) where
798800 toConstr _ = error " toConstr"
799801 gunfold _ _ = error " gunfold"
800802 dataTypeOf _ = mkNoRepType " Data.Primitive.Array.MutableArray"
803+
804+ -- | Create any number of arrays of the same type within an arbitrary
805+ -- 'Traversable' context. This will often be useful with traversables
806+ -- like @(c,)@, @'Either' e@, @'Compose' (c,) ('Either' e)@, and
807+ -- @'Compose' ('Either' e) (c,)@. For a more general version, see
808+ -- 'runArraysHetOf'.
809+ runArrays
810+ :: Traversable t
811+ => (forall s . ST s (t (MutableArray s a )))
812+ -> t (Array a )
813+ runArrays m = runST $ m >>= traverse unsafeFreezeArray
814+
815+ -- | Create arbitrarily many arrays that may have different types.
816+ -- For a simpler but less general version, see 'runArrays'.
817+ --
818+ -- === __Examples__
819+ --
820+ -- ==== @'runArrays'@
821+ --
822+ -- @
823+ -- newtype Ha t a v = Ha {unHa :: t (v a)}
824+ -- runArrays m = unHa $ runArraysHetOf (\f (Ha t) -> Ha <$> traverse f t) (Ha <$> m)
825+ -- @
826+ --
827+ -- ==== @unzipArray@
828+ --
829+ -- @
830+ -- unzipArray :: Array (a, b) -> (Array a, Array b)
831+ -- unzipArray ar =
832+ -- unPair $ runArraysHetOf traversePair $ do
833+ -- xs <- newArray sz undefined
834+ -- ys <- newArray sz undefined
835+ -- let go k
836+ -- | k == sz = pure (Pair (xs, ys))
837+ -- | otherwise = do
838+ -- (x,y) <- indexArrayM ar k
839+ -- writeArray xs k x
840+ -- writeArray ys k y
841+ -- go (k + 1)
842+ -- go 0
843+ -- where sz = sizeofArray ar
844+ --
845+ -- data Pair ab v where
846+ -- Pair :: {unPair :: (v a, v b)} -> Pair (a,b) v
847+ --
848+ -- traversePair :: Applicative h => (forall x. f x -> h (g x)) -> Pair ab f -> h (Pair ab g)
849+ -- traversePair f (Pair (xs, ys)) = liftA2 (\x y -> Pair (x,y)) (f xs) (f ys)
850+ -- @
851+ runArraysHetOf
852+ :: (forall h f g .
853+ (Applicative h => (forall x . f x -> h (g x )) -> t f -> h (u g ))) -- ^ A rank-2 traversal
854+ -> (forall s . ST s (t (MutableArray s ))) -- ^ An 'ST' action producing a rank-2 container of 'MutableArray's.
855+ -> u Array
856+ runArraysHetOf f m = runST $ m >>= f unsafeFreezeArray
0 commit comments