Here’s an extract from the documentation of evaluate:
Control.Exception.Base.evaluate :: a -> IO a
evaluate xis not the same as
return $! xA 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
evaluateis:seqhas the typea -> b -> b. It firstly evaluates the first argument, then returns the second argument.Evaluate follows these three rules:
The difference between the
return $! xand(return $! x) >>= returnbecomes apparent with this expression:By the first rule, that must evaluate to 42.
With the
return $! xdefinition, the above expression would cause an undefined exception. This has the value ⊥, which doesn’t equal 42.With the
(return $! x) >>= returndefinition, it does equal 42.Basically, the
return $! xform 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.