@@ -628,68 +628,33 @@ parFmap strat f = (`using` parTraversable strat) . fmap f
628628-- --------------------------------------------------------------------------
629629-- Strategies for lazy lists
630630
631- -- List-based non-compositional rolling buffer strategy, evaluating list
632- -- elements to weak head normal form.
633- -- Not to be exported; used in evalBuffer and for optimisation.
634- evalBufferWHNF :: Int -> Strategy [a ]
635- evalBufferWHNF n0 xs0 = return (ret xs0 (start n0 xs0))
636- where -- ret :: [a] -> [a] -> [a]
637- ret (x: xs) (y: ys) = y `pseq` (x : ret xs ys)
638- ret xs _ = xs
639-
640- -- start :: Int -> [a] -> [a]
641- start 0 ys = ys
642- start ! _n [] = []
643- start ! n (y: ys) = y `pseq` start (n- 1 ) ys
644-
645- -- | 'evalBuffer' is a rolling buffer strategy combinator for (lazy) lists.
646- -- Evaluation of the ith element induces evaluation of the (i+n)th element,
647- -- with the first n elements being evaluated immediately.
648- --
649- -- 'evalBuffer' is not as compositional as the type suggests. In fact,
650- -- it evaluates list elements at least to weak head normal form,
651- -- disregarding a strategy argument 'r0'.
652- --
653- -- > evalBuffer n r0 == evalBuffer n rseq
654- --
631+ -- | 'evalBuffer' is a rolling buffer strategy combinator for lazy lists.
632+ -- Pattern matching on the result of @evalBuffer n strat xs@ will evaluate the
633+ -- first @n+1@ elements of @xs@ using @strat@. Pattern matching on each
634+ -- additional list cons will evaluate an additional element using @strat@.
655635evalBuffer :: Int -> Strategy a -> Strategy [a ]
656- evalBuffer n strat = evalBufferWHNF n . map (withStrategy strat)
657-
658- -- Like evalBufferWHNF, but sparks the list elements when pushing them
659- -- into the buffer.
660- -- Not to be exported; used in parBuffer and for optimisation.
661- parBufferWHNF :: Int -> Strategy [a ]
662- parBufferWHNF n0 xs0 = return (ret xs0 (start n0 xs0))
663- where -- ret :: [a] -> [a] -> [a]
664- ret (x: xs) (y: ys) = y `par` (x : ret xs ys)
665- ret xs _ = xs
666-
667- -- start :: Int -> [a] -> [a]
668- start 0 ys = ys
669- start ! _n [] = []
670- start ! n (y: ys) = y `par` start (n- 1 ) ys
671-
672-
673- -- | Like 'evalBuffer', but evaluates the list elements in parallel when
674- -- pushing them into the buffer.
675- -- Evaluation of the ith element induces parallel evaluation of the (i+n)th element,
676- -- with the first n elements being evaluated in parallel immediately.
677- --
678- -- > parBuffer n strat = evalBuffer n (rparWith strat)
636+ evalBuffer n0 strat xs0 = return (ret tied (drop n0 tied))
637+ where
638+ -- This is the heart of the strategy. The idea is to tie the evaluation
639+ -- of each cons (to WHNF) to the evaluation of its contents (according
640+ -- to strat). Walking the spine of the result will thus perform
641+ -- the requested Eval actions.
642+ tied = foldr go [] xs0
643+ where
644+ go x r = runEval ((: r) <$> strat x)
645+
646+ ret (x : xs) (_y : ys) = x : ret xs ys
647+ ret xs _ = xs
648+
649+ -- | 'parBuffer' is a rolling buffer strategy combinator for lazy lists.
650+ -- Pattern matching on the result of @parBuffer n s xs@ sparks
651+ -- computations to evaluate the first @n+1@ elements of @xs@ using the
652+ -- strategy @s@. Pattern matching on each additional list cons will
653+ -- spark an additional computation.
654+ --
655+ -- @parBuffer n strat = 'evalBuffer' n ('rparWith' strat)@
679656parBuffer :: Int -> Strategy a -> Strategy [a ]
680- parBuffer n strat = parBufferWHNF n . map (withStrategy strat)
681- -- Alternative definition via evalBuffer (may compromise firing of RULES):
682- -- parBuffer n strat = evalBuffer n (rparWith strat)
683-
684- -- Deforest the intermediate list in parBuffer/evalBuffer when it is
685- -- unnecessary:
686-
687- {-# NOINLINE [1] evalBuffer #-}
688- {-# NOINLINE [1] parBuffer #-}
689- {-# RULES
690- "evalBuffer/rseq" forall n . evalBuffer n rseq = evalBufferWHNF n
691- "parBuffer/rseq" forall n . parBuffer n rseq = parBufferWHNF n
692- #-}
657+ parBuffer n strat = evalBuffer n (rparWith strat)
693658
694659-- --------------------------------------------------------------------------
695660-- Strategies for tuples
0 commit comments