2016-07-04 35 views
1

考慮:推理`parMap`

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 -> Eval b更換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

+0

在擴展'parMap'時,你忘記了最後一個'[a]'參數。 – chepner

回答

4

您的解釋存在錯誤,Strategy不是類型類型,而是類型別名。如果檢查parMap的簽名,則Strategy b後跟->,而不是=>,這意味着parMap需要Strategy b作爲第一個參數。 Strategy bb -> Eval b別名這意味着parMap的簽名可以被擴展爲:

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

parMap是不與上述相同的一個,因爲它的簽名是

的主要區別在於第一個版本使用給定的Strategy b從參數(a -> b) -> [a]計算[b],而第二個版本不計算[b]而是計算Eval [b]Eval [b]指定如何生成[b],您必須致電runEval才能使用它。

第一個版本更容易在程序中使用,因爲您不需要撥打runEval,它也更好,因爲評估列表中每個元素的策略並未預先定義,就像在策略爲rpar的書中一樣,但這是一個論據。這意味着第一個版本更通用。看看basic strategies以更好地瞭解您可以傳遞給標準parMap的內容。