关于`parMap`的推理

时间:2016-07-04 20:16:25

标签: haskell

假设:

Prelude Control.Parallel.Strategies> :t parMap
parMap :: Strategy b -> (a -> b) -> [a] -> [b]

Prelude Control.Parallel.Strategies> :i Strategy
type Strategy a = a -> Eval a
        -- Defined in `Control.Parallel.Strategies'

我的理解是parMap可以展开,将b替换为b -> Eval b

parMap :: (a -> b -> Eval b) -> (a -> b -> Eval b) -> [b -> Eval b]

这似乎比Parallel and Concurrent Haskell中的示例版本更复杂:

parMap :: (a -> b) -> [a] -> Eval [b]
parMap f [] = return []
parMap f (a:as) = do
   b <- rpar (f a)
   bs <- parMap f as
   return (b:bs)

parMap的标准库实现中,Strategy b的含义是什么,即a -> b -> Eval b

1 个答案:

答案 0 :(得分:4)

您的解释存在错误,Strategy不是类型类,而是类型别名。如果您检查parMap的签名,则Strategy b后跟->而不是=>,这意味着parMap期望Strategy b为第一个论点。 Strategy bb -> Eval b的别名,这意味着parMap的签名可以扩展为:

parMap :: (b -> Eval b) -> (a -> b) -> [a] -> [b]

书籍parMap与上面的书不同,因为它的签名是

parMap :: (a -> b) -> [a] -> Eval [b]

主要区别在于第一个版本使用给定的Strategy b从参数[b]计算(a -> b) -> [a],而第二个版本不计算[b]但是Eval [b]Eval [b]指定如何生成[b],您必须致电runEval才能使用它。

第一个版本更容易在程序中使用,因为您不需要调用runEval并且它也更好,因为评估列表中每个元素的策略未预定义,就像在战略是rpar的书中一样,但这只是一个论点。这意味着第一个版本更通用。请查看basic strategies,以便更好地了解您可以传递给标准parMap的内容。