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