Учитывая следующие функции для evalPair
, parPair
и deepSeq
соответственно,Почему следующие действия выполняются параллельно, а не последовательно?
evalPair :: Strategy a -> Strategy b -> Strategy (a,b)
evalPair sa sb (a,b) = do
a' <- sa a
b' <- sb b
return (a',b')
parPair :: Strategy a -> Strategy b -> Strategy (a,b)
parPair sa sb = evalPair (rparWith sa) (rparWith sb)
rdeepseq :: NFData a => Strategy a
rdeepseq x = rseq (force x)
Вопрос, почему будет следующий код будет оцениваться параллельно, как утверждает автор?
parPair rdeepseq rdeepseq :: (NFData a, NFData b) => Strategy (a,b)
Я в собой своем, так как Саймон Марлоу говорит следующее
Чтобы сломать то, что происходит, когда эта
Strategy
применяется к паре:parPair
звонковevalPair
иevalPair
вызовыrparWith rdeepseq
на каждый компоненты пары. Таким образом, эффект заключается в том, что каждый компонент будет равен , который будет полностью оцениваться в нормальной форме параллельно.
Согласно тому, что я вижу rparWith rdeepseq
это неформально rpar . rseq . force
что означает, что аргумент будет оцениваться к нормальной форме, которую она будет оцениваться с rseq
последовательно, и, следовательно, в конце концов rpar
не имеет никакого использования в параллельном контексте ,
Все взято из книги Симона Марлоу.
Заранее спасибо.
Таким образом, ваш ответ будет означать, что мое понимание состава стратегии было неверным (т. Е. RparWith rdeepseq == rpar. Rseq. Force в основном неверно)? BTW спасибо за ответ. – McGill
@McGill: нет, это совершенно нормально (ну, за исключением отсутствующей «точки», поскольку вы не можете составлять стратегии с помощью '(.)') Но '(.) Fgx' является' f (gx) ', поэтому' (rpar. rseq. force) x' является 'rpar (rseq (force x))'. В других языках программирования нам нужно было бы оценить 'force x', чтобы использовать' rseq'. Но поскольку Haskell не является строгим, мы фактически не оцениваем аргументы в 'rpar'. Вместо этого мы передаем '' на 'rpar', который _then_ искры' 'для параллельной оценки. –
Zeta