module Data.TreeFold.Parallel
(treeFold
,treeFoldNonEmpty
,treeFoldMap
,treeFoldMapNonEmpty)
where
import Data.List.NonEmpty (NonEmpty (..))
import Control.Parallel (par, pseq)
import GHC.Conc (numCapabilities)
import qualified Data.TreeFold as Lazy
treeFold :: (a -> a -> a) -> a -> [a] -> a
treeFold f z xs =
Lazy.treeFoldMap const (splitPar f) (const z) xs numCapabilities
splitPar :: (a -> a -> a) -> (Int -> a) -> (Int -> a) -> Int -> a
splitPar f = go
where
go l r 0 = lt `seq` rt `seq` f lt rt
where
lt = l 0
rt = r 0
go l r n = lt `par` (rt `pseq` f lt rt)
where
lt = l m
rt = r m
m = n `div` 2
treeFoldNonEmpty :: (a -> a -> a) -> NonEmpty a -> a
treeFoldNonEmpty f xs =
Lazy.treeFoldMapNonEmpty const (splitPar f) xs numCapabilities
treeFoldMap :: (b -> a) -> (a -> a -> a) -> a -> [b] -> a
treeFoldMap c f z xs =
Lazy.treeFoldMap (const . c) (splitPar f) (const z) xs numCapabilities
treeFoldMapNonEmpty :: (b -> a) -> (a -> a -> a) -> NonEmpty b -> a
treeFoldMapNonEmpty c f xs =
Lazy.treeFoldMapNonEmpty (const . c) (splitPar f) xs numCapabilities