2017-01-25 3 views
1

Учитывая следующие функции для 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 не имеет никакого использования в параллельном контексте ,

Все взято из книги Симона Марлоу.


Заранее спасибо.

ответ

3

Давайте посмотрим на parPair rdeepseq rdeepseq:

parPair rdeepseq rdeepseq (a,b) 
= evalPair (rparWith rdeepseq) (rparWith rdeepseq) (a,b) 
= do 
    a' <- rparWith rdeepseq a 
    b' <- rparWith rdeepseq b 
    return (a', b') 

Так как rparWith искры это аргументы, rdeepseq a будут оцениваться параллельно (возможно). Это было бы не параллельно, если бы вы использовали

evalPair rdeepseq rdeepseq 

вместо этого. rparWith имеет важное значение, так как он искривляет свой аргумент для оценки с помощью данной стратегии.

+0

Таким образом, ваш ответ будет означать, что мое понимание состава стратегии было неверным (т. Е. RparWith rdeepseq == rpar. Rseq. Force в основном неверно)? BTW спасибо за ответ. – McGill

+1

@McGill: нет, это совершенно нормально (ну, за исключением отсутствующей «точки», поскольку вы не можете составлять стратегии с помощью '(.)') Но '(.) Fgx' является' f (gx) ', поэтому' (rpar. rseq. force) x' является 'rpar (rseq (force x))'. В других языках программирования нам нужно было бы оценить 'force x', чтобы использовать' rseq'. Но поскольку Haskell не является строгим, мы фактически не оцениваем аргументы в 'rpar '. Вместо этого мы передаем '' на 'rpar', который _then_ искры' 'для параллельной оценки. – Zeta