I understand (I think) that Haskell's seq
, will (generally) reduce its first argument to WHNF, and see this behavior as expected in GHCi:
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0
foo
0
However, though the documentation for evaluate
says that it also reduces its argument to WHNF, it looks like it actually fully reduces its argument to normal form:
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x
foo
Foo bar
(Bar 100)
I can confirm this (apparent) discrepancy with
λ> let y = (trace "foo" Foo (trace "bar" Bar 100))
λ> seq y 0
foo
0
λ> :sprint y
y = <Foo> _
and
λ> let z = (trace "foo" Foo (trace "bar" Bar 100))
λ> evaluate z
foo
Foo bar
(Bar 100)
λ> :sprint z
z = <Foo> (<Bar> 100)
If the documentation for evaluate
is correct, shouldn't the behavior of seq
and evaluate
be the same? What am I missing here (as a Haskell beginner)?
To determine whether an expression is in weak head normal form, we only have to look at the outermost part of the expression. If it's a data constructor or a lambda, it's in weak head normal form. If it's a function application, it's not.
From HaskellWiki. An expression is in weak head normal form (WHNF), if it is either: a constructor (eventually applied to arguments) like True , Just (square 42) or (:) 1 . a built-in function applied to too few arguments (perhaps none) like (+) 2 or sqrt . or a lambda abstraction \x -> expression .
From HaskellWiki. The seq function is the most basic method of introducing strictness to a Haskell program. seq :: a -> b -> b takes two arguments of any type, and returns the second. However, it also has the important property that it is magically strict in its first argument.
What you are missing is that GHCi also prints the result of IO actions (if they can be shown and are not ()
), which does cause it to evaluate to normal form. Try instead:
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With