我有一个基本上执行以下操作的计算:
f :: [a] -> ([b],Bool)
这个函数其实可以写
f = foldr h ([],False) . map g
where h (b,bool) (bs,boolSoFar) = (b:bs,bool || boolSoFar)
哪里g :: a -> (b,Bool)
有一些需要花费大量时间的功能。f 通常在小列表上调用,因此尝试并行计算地图似乎很有趣。这可以通过 Control.Parallel.Strategies parMap 来完成。所以现在我们使用
f = foldr h ([],False) . parMap rseq g
where h (b,bool) (bs,boolSoFar) = (b:bs, bool || boolSoFar)
这一切都很好。现在,您会注意到可以在f
. 即,我可以使用 map-fold fusion 将其编写为单个折叠,因此循环遍历列表。但是,这样我就失去了做并行的好处。
现在,有人可能会说,在 的第二个定义中f
,再次循环遍历列表并不是那么糟糕,那么为什么不直接这样做呢。我想我在想的是,如果 Haskell 有可变变量,那么可以在 map 的主体中更新这个布尔变量(我想你必须锁定和解锁它)。做这样的事情有什么建议吗?