a variant of
deepseq that is useful in some circumstances:
force x = x `deepseq` x
force x fully evaluates
x, and then returns it. Note
that
force x only performs evaluation when the value of
force x itself is demanded, so essentially it turns shallow
evaluation into deep evaluation.
force can be conveniently used in combination with
ViewPatterns:
{-# LANGUAGE BangPatterns, ViewPatterns #-}
import Control.DeepSeq
someFun :: ComplexData -> SomeResult
someFun (force -> !arg) = {- 'arg' will be fully evaluated -}
Another useful application is to combine
force with
evaluate in order to force deep evaluation relative to other
IO operations:
import Control.Exception (evaluate)
import Control.DeepSeq
main = do
result <- evaluate $ force $ pureComputation
{- 'result' will be fully evaluated at this point -}
return ()
Finally, here's an exception safe variant of the
readFile'
example:
readFile' :: FilePath -> IO String
readFile' fn = bracket (openFile fn ReadMode) hClose $ \h ->
evaluate . force =<< hGetContents h