更新:我刚刚找到this documentation page。希望从the documentation that I'd been using链接到它,这似乎是权威的API文档。但这也许是一项未发布的新作品。
更新2 :本文档为我提供了如何使用Control.Parallel.Strategies模块的更好的主意。但是我还没有完全解决问题...请参阅问题结尾。
我一直在尝试在Haskell中使用parListChunk或其他一些并行控制功能。但是我不知道如何使用它们。警告:我是Haskell新手。大约20年前,我了解了使用Scheme进行函数式编程的一些知识(!)。
这是我的非并行函数:
possibKs n r = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ]
我想并行化它,就像这样的天真尝试:
possibKs n r
| n < parCutoff = results
| otherwise = parListChunk parChunkSize results
where results = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ]
但是,这种结构不适用于parListChunk。
文档说:
parListChunk :: Int -> Strategy a -> Strategy [a]
好,那是我想要的。但是如何使用呢?我还没有找到任何这样的例子。如果我了解类型声明,则parListChunk是一个函数,该函数接受
Int
和Strategy<a>
(借用C++参数化的类型表示法以帮助检查我是否真正理解了此权限),并返回Strategy<[a]>
。在我的情况下,我正在处理Int
的a
,因此parListChunk将需要一个Int
参数和一个Strategy<Int>
。那么什么是Strategy
,我该如何产生呢?一旦我成功使用了parListChunk,如何处理它发出的Strategy
怎么办?Strategy type is defined像这样:
type Strategy a = a -> Done
(这就是所有战略文档。)
因此,
Strategy<Int>
是一个接受Int类型参数并返回Done的函数。显然,它会导致其参数在某个时间或某个时刻得到评估。我在哪里可以得到一个,应该使用哪种类型?以下功能似乎可以返回“策略”:
sPar :: a -> Strategy b
sSeq :: a -> Strategy b
r0 :: Strategy a
rwhnf :: Strategy a
但是它们都不能让您确定类型参数-当您提供参数
Strategy<b>
时它们会生成a
,否则您将无法提供参数a
!那是怎么回事??除此之外,我不知道这些是什么意思。我确实在SO上找到了类似函数parList being used的一个示例:
return . maximum $ map optimize xs `using` parList
它使用了这个时髦的
using
函数,该函数声明为:using :: a -> Strategy a -> a
足够公平...就我而言,我可能希望
a
为[Int]
,因此它接受一个Ints和一个Strategy<[Int]>
的列表,并且(执行某些操作?将该策略应用于该列表?并)返回一个Ints列表。因此,我尝试遵循parList示例,并将otherwise
保护更改为:| otherwise = results `using` parListChunk parChunkSize
但我必须承认,我仍在黑暗中射击...我不太了解周围的类型签名。因此,上面给出了一个错误也就不足为奇了:
Couldn't match expected type `[(Int, Integer)]'
against inferred type `a -> Eval a'
Probable cause: `parListChunk' is applied to too few arguments
In the second argument of `using', namely
`parListChunk parChunkSize'
In the expression: results `using` parListChunk parChunkSize
有人可以告诉我parListChunk的
Strategy a
参数使用什么吗?以及如何使用parListChunk返回的Strategy [a]
?新部分
看Basic Strategies,我认为我需要使用
rseq
策略。大概。所以我尝试| otherwise = results `using` (parListChunk parChunkSize rseq)
但GHC表示,rseq不在“范围内”。
These API docs表示软件包中没有rseq,但sSeq似乎已替换了它。好的,所以我使用了sSeq,但是它也不在范围内。即使我正在导入
Control.Parallel.Strategies
。有什么线索吗?顺便说一句,我曾经获得有关加载程序包的这些消息:
Loading package deepseq-1.1.0.0 ... linking ... done.
Loading package parallel-2.2.0.1 ... linking ... done.
显然,这表明我拥有并行软件包的哪个版本:2.2.0.1。但是我在API docs中看不到有关描述哪个版本的信息。如果我不应该使用rseq或sSeq,应该使用什么? Edward为何能够使用parList?
最佳答案
好的,我的代码可以正常工作了。我通过使用rwhnf
而不是rseq
进行编译:
| otherwise = results `using` (parListChunk parChunkSize rwhnf)
根据this source code的说法,
rwhnf
在版本3中被重命名为rseq
。因此,我猜我的Parallel软件包的版本相对于this documentation已经过时了。 :-S我想这是使用“实验”软件包的一部分价格。
无论如何,代码会编译并运行。它对并行性是否有用呢?这是另一个问题。
关于haskell - 如何在Haskell Control.Parallel.Strategies中制定策略?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3679729/