Haskell "оценивает" сводится к нормальному или WHNF?

Я понимаю ( я думаю), что Хаскелла seq(в общем случае) уменьшит свой первый аргумент до WHNF и увидит такое поведение, как и ожидалось в GHCi:

λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0
foo
0

Тем не менее, хотя документация дляevaluate говорит, что он также уменьшает свой аргумент до WHNF, похоже, что он фактически полностью уменьшает свой аргумент до нормальной формы:

λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x
foo
Foo bar
(Bar 100)

Я могу подтвердить это (очевидное) расхождение с

λ> let y = (trace "foo" Foo (trace "bar" Bar 100))
λ> seq y 0
foo
0
λ> :sprint y
y = <Foo> _

а также

λ> let z = (trace "foo" Foo (trace "bar" Bar 100))
λ> evaluate z
foo
Foo bar
(Bar 100)
λ> :sprint z
z = <Foo> (<Bar> 100)

Если документация для evaluate правильно, не должно ли поведение seq а также evaluate быть таким же? Что мне здесь не хватает (как новичку в Haskell)?

1 ответ

Решение

Чего вам не хватает, так это того, что GHCi также печатает результат действий ввода-вывода (если они могут быть показаны и не отображаются). ()), что заставляет его оценивать до нормальной формы. Попробуйте вместо этого:

λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo
Другие вопросы по тегам