diff options
author | Roman Cheplyaka <roma@ro-che.info> | 2015-02-09 13:44:03 -0600 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2015-02-09 21:07:26 -0600 |
commit | de9a836cd920722a4c28dcb464ff2c8d5905acb9 (patch) | |
tree | 88ffc6a11e03ad8134eb703663f8c0c583459549 | |
parent | e22282e5d2a370395535df4051bdeb8213106d1c (diff) | |
download | haskell-de9a836cd920722a4c28dcb464ff2c8d5905acb9.tar.gz |
Clarify the documentation for 'evaluate'
Summary:
See:
https://www.haskell.org/pipermail/ghc-devs/2015-January/007900.html
https://ghc.haskell.org/trac/ghc/ticket/5129#comment:17
Reviewers: hvr, Mikolaj, austin
Reviewed By: Mikolaj, austin
Subscribers: ezyang, nomeata, thomie
Differential Revision: https://phabricator.haskell.org/D615
-rw-r--r-- | libraries/base/GHC/IO.hs | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/libraries/base/GHC/IO.hs b/libraries/base/GHC/IO.hs index e9ac94103d..7dbd3382f9 100644 --- a/libraries/base/GHC/IO.hs +++ b/libraries/base/GHC/IO.hs @@ -470,20 +470,39 @@ a `finally` sequel = _ <- sequel return r --- | 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 the argument to weak head normal form. -- --- > evaluate x `seq` y ==> y --- > evaluate x `catch` f ==> (return $! x) `catch` f --- > evaluate x >>= f ==> (return $! x) >>= f +-- 'evaluate' is typically used to uncover any exceptions that a lazy value +-- may contain, and possibly handle them. -- --- /Note:/ the first equation implies that @(evaluate x)@ is /not/ the --- same as @(return $! x)@. A correct definition is +-- 'evaluate' only evaluates to /weak head normal form/. If deeper +-- evaluation is needed, the @force@ function from @Control.DeepSeq@ +-- may be handy: -- --- > evaluate x = (return $! x) >>= return +-- > evaluate $ force x -- +-- There is a subtle difference between @'evaluate' x@ and @'return' '$!' x@, +-- analogous to the difference between 'throwIO' and 'throw'. If the lazy +-- value @x@ throws an exception, @'return' '$!' x@ will fail to return an +-- 'IO' action and will throw an exception instead. @'evaluate' x@, on the +-- other hand, always produces an 'IO' action; that action will throw an +-- exception upon /execution/ iff @x@ throws an exception upon /evaluation/. +-- +-- The practical implication of this difference is that due to the +-- /imprecise exceptions/ semantics, +-- +-- > (return $! error "foo") >> error "bar" +-- +-- may throw either @"foo"@ or @"bar"@, depending on the optimizations +-- performed by the compiler. On the other hand, +-- +-- > evaluate (error "foo") >> error "bar" +-- +-- is guaranteed to throw @"foo"@. +-- +-- The rule of thumb is to use 'evaluate' to force or handle exceptions in +-- lazy values. If, on the other hand, you are forcing a lazy value for +-- efficiency reasons only and do not care about exceptions, you may +-- use @'return' '$!' x@. evaluate :: a -> IO a evaluate a = IO $ \s -> seq# a s -- NB. see #2273, #5129 - |