In the Haskell Performance Resource wiki-section, the not further explained recommendation is given to
- Use strict returns (
return $! ...
) unless you absolutely need them lazy.
Why is that a good thing to do? When exactly is the ...
-expression (Whnf-)forced?
Given the "Left identity" monad-law and the definition
f $! x = x `seq` f x
I can rewrite (in do
-notation`):
do x' <- return $! x
f x'
to
do x' <- x `seq` return x
f x'
But it seems I can't get to
do f $! x
PS: If the BangPatterns
-extension is available, is
do !x' <- return x
f x'
semantically the same as the first do
-expression given above?
There's a reason you can't get from
do x' <- x `seq` return x
f x'
to
f $! x
It's because they are not the same. Just expand the do notation:
(x `seq` return x) >>= (\ x' -> f x')
The seq
will only be evaluated if the (>>=)
is strict in its first argument. That's not necessarily true.
For IO there is also the useful Control.Exception.evaluate:
Forces its argument to be evaluated to weak head normal form when the resultant IO action is executed. It can be used to order evaluation with respect to other IO operations; its semantics are given by
evaluate :: a -> IO a
evaluate x = (return $! x) >>= return
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