Here's an extract from the documentation of evaluate
:
Control.Exception.Base.evaluate :: a -> IO a
evaluate x
is not the same as
return $! x
A correct definition is
evaluate x = (return $! x) >>= return
(source)
These seem to have the same meaning. What is the difference between these two definitions?
Quick ref:
The type of evaluate
is:
evaluate :: a -> IO a
seq
has the type a -> b -> b
. It firstly evaluates the first argument, then returns the second argument.
Evaluate follows these three rules:
evaluate x `seq` y ==> y
evaluate x `catch` f ==> (return $! x) `catch` f
evaluate x >>= f ==> (return $! x) >>= f
The difference between the return $! x
and (return $! x) >>= return
becomes apparent with this expression:
evaluate undefined `seq` 42
By the first rule, that must evaluate to 42.
With the return $! x
definition, the above expression would cause an undefined exception. This has the value ⊥, which doesn't equal 42.
With the (return $! x) >>= return
definition, it does equal 42.
Basically, the return $! x
form is strict when the IO value is calculated. The other form is only strict when the IO value is run and the value used (using >>=
).
See this mailing list thread for more details.
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