我偶然发现了Eval
monad 和rpar
Strategy
Haskell 的问题。考虑以下代码:
module Main where
import Control.Parallel.Strategies
main :: IO ()
main = print . sum . inParallel2 $ [1..10000]
inParallel :: [Double] -> [Double]
inParallel xss = runEval . go $ xss
where
go [] = return []
go (x:xs) = do
x' <- rpar $ x + 1
xs' <- go xs
return (x':xs')
inParallel2 :: [Double] -> [Double]
inParallel2 xss = runEval . go $ xss
where
go [] = return []
go [x] = return $ [x + 1]
go (x:y:xs) = do
(x',y') <- rpar $ (x + 1, y + 1)
xs' <- go xs
return (x':y':xs'
我像这样编译并运行它:
ghc -O2 -Wall -threaded -rtsopts -fforce-recomp -eventlog eval.hs
./eval +RTS -N3 -ls -s
当我使用inParallel
函数并行性按预期工作时。在输出运行时统计信息中,我看到:
SPARKS: 100000 (100000 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
当我切换到inParallel2
功能时,所有并行性都消失了:
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
为什么元组的评估不能并行工作?在将元组传递给 rpar 之前,我尝试强制执行该元组:
rpar $!! (x + 1, y + 1)
但仍然没有结果。我究竟做错了什么?