deepseq
deepseq copied to clipboard
($!!) seems to be implemented incorrectly
Current implementation of $!! is:
deepseq :: NFData a => a -> b -> b
deepseq a b = rnf a `seq` b
($!!) :: (NFData a) => (a -> b) -> a -> b
f $!! x = x `deepseq` f x
-- f $!! x = rnf x `seq` f x
However per documentation of seq and deepseq the second argument may be evaluated before the first one. This means that means that f x may be evaluated before rnf x.
Probably this should be changed to:
($!!) :: (NFData a) => (a -> b) -> a -> b
f $!! x = let f' = rnf x `seq` f in f' x
This way f may be evaluated before rnf x but f' x/f x will be evaluated after rnf x.
It looks like the documentation for $!! is wrong. There's no guarantee of evaluation order with $! or $!!
Similarly the Haskell Report specifies the behavior of $! as f $! x = x ‘seq‘ f x
@uzytkownik would you like to prepare a PR fixing the documentation?