О "pseq" в Haskell

Рассмотрим следующие два утверждения:

(a `par` b) `pseq` (a + b)

и

a `par` (b `pseq` (a + b))

Может кто-нибудь объяснить, как их поведение отличается друг от друга?

Для первого, если основной поток выполнил с вычислением b, но искровое вычисление a еще не закончено, начнет ли основной поток вычислять a + b?

Ответ 1

par a b семантически эквивалентен b, но он дает подсказку, что было бы полезно начать раннюю оценку a. С другой стороны, pseq заставляет оценивать свой первый аргумент, но является просто (ленивой) функцией идентичности во втором аргументе.

Итак,

(a `par` b) `pseq` (a + b)

семантически эквивалентно

b `pseq` (a + b)

что эквивалентно

a `par` (b `pseq` (a + b))

в том смысле, что обе говорят: "Оцените b, затем станьте темпом a + b". Учитывая неточность в последствиях par, никакое другое отличие не может сравниться с определением языка. Скорее, в вашем конкретном компиляторе/времени выполнения они могут делать несколько разные вещи.