Skip to content

parBufferWHNF could be less subtle

I would suggest modifying parBufferWHNF as follows, with the {- x ``seq`` -} actually included.

parBufferWHNF :: Int -> Strategy [a]
parBufferWHNF n0 xs0 = return (ret xs0 (start n0 xs0))
  where -- ret :: [a] -> [a] -> [a]
    ret (x:xs) (y:ys) = y `par` (x : ({-x `seq`-} ret xs ys))
    ret xs     _      = xs

    -- start :: Int -> [a] -> [a]
    start 0   ys     = ys
    start !_n []     = []
    start !n  (y:ys) = y `par` start (n-1) ys

The point of the extra x ``seq`` is so that consumers that do not evaluate the list element before evaluating the next cons cell don't get such surprising loss of parallelism. For example non-strict left folds like sum will rush to the end of the list spine without evaluating the list elements, and then evaluate the elements later. That does not work well with the parBufferWHNF strategy. Adding the extra seq fixes it. Note that in this case I think seq or pseq would work.

Trac metadata
Trac field Value
Version 7.2.1
Type FeatureRequest
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries (other)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information