向并行代码添加进度条(Haskell)

在 Haskell 中,我有一个可以并行计算的列表。每个单独的评估不需要那么长时间,但有很多(例如,100 万)。我正在使用以下库。该计划将列表拆分为多个块并并行运行它们。我有类似以下的东西:

import Control.Parallel.Strategies
import Control.DeepSeq

-- Imagine this being slightly more expensive
kindaExpensiveComputation :: Int -> [Int]
kindaExpensiveComputation n = replicate n 42

main :: IO ()
main = do
    let n = 1000000
    let args = replicate n 20
    let chunkSize = n `div` 10
    let result = force $ withStrategy (parListChunk chunkSize rseq) . map kindaExpensiveComputation $ args
    -- do stuff with result here
    -- end program

我想为此添加一个进度条,以便我可以跟踪已完成的列表数量。我的直觉是尝试以下操作:

import Control.Parallel.Strategies
import Control.DeepSeq
import System.ProgressBar

-- Imagine this being slightly more expensive
kindaExpensiveComputation :: ProgressBar s -> Int -> IO [Int]
kindaExpensiveComputation pb n = do
    let res = replicate n 42
    incProgress pb 1
    return res

main :: IO ()
main = do
    let n = 1000000
    let args = replicate n 20
    let chunkSize = n `div` 10
    pb <- newProgressBar defStyle 10 (Progress 0 n ())
    let result = force $ withStrategy (parListChunk chunkSize rseq) . map (kindaExpensiveComputation pb) $ args
    -- do stuff with result here
    -- end program

force似乎无法处理IO。我已经尝试了其他一些事情,但是无论我尝试什么IO [Int],都会并行评估IO. 我看到并行库有一些函数,比如withStrategyIO,虽然我不确定如何使用它或者它是否是我正在寻找的。

我认为我对 Haskell 如何评估表达式的理解引起了我的困惑,因此任何有关此的指示也会有所帮助。

以上是向并行代码添加进度条(Haskell)的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>