repa-array-4.2.2.1: Data/Repa/Array/Internals/Operator/Group.hs
-- | Grouping operations on arrays.
module Data.Repa.Array.Internals.Operator.Group
( groups
, groupsWith
, GroupsDict)
where
import Data.Repa.Array.Generic.Index as A
import Data.Repa.Array.Meta.Tuple as A
import Data.Repa.Array.Internals.Bulk as A
import Data.Repa.Array.Internals.Target as A
import Data.Repa.Eval.Chain as A
import qualified Data.Repa.Chain as C
#include "repa-array.h"
-- | From a stream of values which has consecutive runs of idential values,
-- produce a stream of the lengths of these runs.
--
-- @
-- > import Data.Repa.Array.Material
-- > import Data.Repa.Nice
-- > nice $ groups U U (fromList U "waaabllle")
-- ([('w',1),('a',3),('b',1),('l',3)],Just ('e',1))
-- @
--
groups :: (GroupsDict lElt lGrp tGrp lLen tLen n, Eq n)
=> Name lGrp -- ^ Layout for group names.
-> Name lLen -- ^ Layout gor group lengths.
-> Array lElt n -- ^ Input elements.
-> (Array (T2 lGrp lLen) (n, Int), Maybe (n, Int))
groups nGrp nLen arr
= groupsWith nGrp nLen (==) Nothing arr
{-# INLINE groups #-}
-- | Like `groups`, but use the given function to determine whether two
-- consecutive elements should be in the same group. Also take
-- an initial starting group and count.
--
-- @
-- > import Data.Repa.Array.Material
-- > import Data.Repa.Nice
-- > nice $ groupsWith U U (==) (Just ('w', 5)) (fromList U "waaabllle")
-- ([('w',6),('a',3),('b',1),('l',3)],Just ('e',1))
-- @
--
groupsWith
:: GroupsDict lElt lGrp tGrp lLen tLen n
=> Name lGrp -- ^ Layout for group names.
-> Name lLen -- ^ Layout for group lengths.
-> (n -> n -> Bool) -- ^ Comparison function.
-> Maybe (n, Int) -- ^ Starting element and count.
-> Array lElt n -- ^ Input elements.
-> (Array (T2 lGrp lLen) (n, Int), Maybe (n, Int))
groupsWith nGrp nLen f !c !vec0
= (vec1, snd k1)
where
f' x y = return $ f x y
{-# INLINE f' #-}
(vec1, k1)
= A.unchainToArray (T2 nGrp nLen)
$ C.liftChain
$ C.groupsByC f' c
$ A.chainOfArray vec0
{-# INLINE_ARRAY groupsWith #-}
-- | Dictionaries need to perform a grouping.
type GroupsDict lElt lGrp tGrp lLen tLen n
= ( Bulk lElt n
, Target lGrp n
, Target lLen Int
, Index lGrp ~ Index lLen)