Sposób myśleć o a `seq` b
nie jest to, że „ocenia a
”, ale to, że tworzy zależność między a
i b
, tak że kiedy idziesz do oceny b
ocenić a
również.
Oznacza to na przykład, że a `seq` a
jest całkowicie zbędny: mówisz Haskellowi, aby ocenił a
podczas oceny a
. Zgodnie z tą samą logiką, seq a
z jednym argumentem nie będzie niczym innym niż samo pisanie a
.
Po prostu seq a
, że jakoś ocenia a
nie będzie działać. Problem polega na tym, że seq a
sam jest wyrażeniem, które może nie zostać ocenione - na przykład może znajdować się głęboko w niektórych zagnieżdżonych porachunkach. Tak więc stanie się to istotne tylko wtedy, gdy dojdziesz do oceny całego wyrażenia seq a
- w którym momencie i tak sam byś ocenił a
.
@ Przykład Rhymoid, w jaki sposób jest używany w ścisłym fałdowaniu (foldl'
), jest dobry. Naszym celem jest napisanie takiego fałdu, aby jego pośrednia skumulowana wartość (acc
) była w pełni oceniana na każdym etapie, gdy tylko oceniamy wynik końcowy. Odbywa się to poprzez dodanie seq
między skumulowanej wartości i rekurencyjnego wywołania:
foldl' f z (x:xs) =
let z' = f z x in z' `seq` foldl' f z' xs
Można wizualizacji tego, jak długi łańcuch seq
pomiędzy każdym zastosowaniu f
w owczarni, łącząc je wszystkie do wyniku końcowego . W ten sposób podczas oceniania końcowego wyrażenia (tj. Liczby, którą uzyskuje się przez zsumowanie listy), ocenia ona bezpośrednio wartości pośrednie (tj. Sumy częściowe podczas składania przez listę).
Jeśli spojrzysz na [(bardzo źle sformatowaną) definicję 'foldl''' (https://wiki.haskell.org/Seq), zauważysz, że często chcesz po prostu ściśle oszacować niektóre zmienne związane z let-bound w 'a', który podajesz do swojej wartości' b'. –