Как выглядит этот код:
parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `par` (nf1+nf2+1))
where nf1 = parfib (n-1)
nf2 = parfib (n-2)
Лучше, чем это:
parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `seq` (nf1+nf2+1))
where nf1 = parfib (n-1)
nf2 = parfib (n-2)
Я не получаю объяснений, которые я нашел в Интернете, которые говорят: «Чтобы гарантировать, что основное выражение оценено в правильном порядке (т.е. без блокировки основной задачи в дочерней задаче), используется аннотация seq» .
Почему используется seq? Я знаю, что это заставляет переводчика сначала оценить parfib (n-1), но зачем это нужно?
При выполнении второй программы не будет ли интерпретатор инициировать новый процесс для оценки nf2 при одновременной оценке nf1 выражения nf1 + nf2 + 1 параллельно? Что нужно сказать ему, чтобы указать, что он должен начинаться с nf1?