elaborate the docs for unsafePerformIO a bit
[ghc-base.git] / GHC / IO.hs
index 865a09c..8a2dd59 100644 (file)
--- a/GHC/IO.hs
+++ b/GHC/IO.hs
@@ -1,5 +1,4 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# OPTIONS_GHC -fno-implicit-prelude -funbox-strict-fields #-}
+{-# OPTIONS_GHC -XNoImplicitPrelude -funbox-strict-fields -XBangPatterns #-}
 {-# OPTIONS_HADDOCK hide #-}
 -----------------------------------------------------------------------------
 -- |
@@ -17,7 +16,7 @@
 
 -- #hide
 module GHC.IO (
-    IO(..), unIO, failIO, liftIO, bindIO, thenIO, returnIO, 
+    IO(..), unIO, failIO, liftIO,
     unsafePerformIO, unsafeInterleaveIO,
     unsafeDupablePerformIO, unsafeDupableInterleaveIO,
     noDuplicate,
@@ -65,40 +64,9 @@ Libraries - parts of hslibs/lang.
 --SDM
 -}
 
-unIO :: IO a -> (State# RealWorld -> (# State# RealWorld, a #))
-unIO (IO a) = a
-
-instance  Functor IO where
-   fmap f x = x >>= (return . f)
-
-instance  Monad IO  where
-    {-# INLINE return #-}
-    {-# INLINE (>>)   #-}
-    {-# INLINE (>>=)  #-}
-    m >> k      =  m >>= \ _ -> k
-    return x    = returnIO x
-
-    m >>= k     = bindIO m k
-    fail s      = failIO s
-
 liftIO :: IO a -> State# RealWorld -> STret RealWorld a
 liftIO (IO m) = \s -> case m s of (# s', r #) -> STret s' r
 
-bindIO :: IO a -> (a -> IO b) -> IO b
-bindIO (IO m) k = IO ( \ s ->
-  case m s of 
-    (# new_s, a #) -> unIO (k a) new_s
-  )
-
-thenIO :: IO a -> IO b -> IO b
-thenIO (IO m) k = IO ( \ s ->
-  case m s of 
-    (# new_s, _ #) -> unIO k new_s
-  )
-
-returnIO :: a -> IO a
-returnIO x = IO (\ s -> (# s, x #))
-
 failIO :: String -> IO a
 failIO s = IO (raiseIO# (toException (userError s)))
 
@@ -133,11 +101,15 @@ This is the \"back door\" into the 'IO' monad, allowing
 this to be safe, the 'IO' computation should be
 free of side effects and independent of its environment.
 
-If the I\/O computation wrapped in 'unsafePerformIO'
-performs side effects, then the relative order in which those side
-effects take place (relative to the main I\/O trunk, or other calls to
-'unsafePerformIO') is indeterminate.  You have to be careful when 
-writing and compiling modules that use 'unsafePerformIO':
+If the I\/O computation wrapped in 'unsafePerformIO' performs side
+effects, then the relative order in which those side effects take
+place (relative to the main I\/O trunk, or other calls to
+'unsafePerformIO') is indeterminate.  Furthermore, when using
+'unsafePerformIO' to cause side-effects, you should take the following
+precautions to ensure the side effects are performed as many times as
+you expect them to be.  Note that these precautions are necessary for
+GHC, but may not be sufficient, and other compilers may require
+different precautions:
 
   * Use @{\-\# NOINLINE foo \#-\}@ as a pragma on any function @foo@
         that calls 'unsafePerformIO'.  If the call is inlined,
@@ -148,7 +120,7 @@ writing and compiling modules that use 'unsafePerformIO':
         two side effects that were meant to be separate.  A good example
         is using multiple global variables (like @test@ in the example below).
 
-  * Make sure that the either you switch off let-floating, or that the 
+  * Make sure that the either you switch off let-floating (@-fno-full-laziness@), or that the 
         call to 'unsafePerformIO' cannot float outside a lambda.  For example, 
         if you say:
         @
@@ -338,7 +310,7 @@ blocked = IO $ \s -> case asyncExceptionsBlocked# s of
                         (# s', i #) -> (# s', i /=# 0# #)
 
 onException :: IO a -> IO b -> IO a
-onException io what = io `catchException` \e -> do what
+onException io what = io `catchException` \e -> do _ <- what
                                                    throw (e :: SomeException)
 
 finally :: IO a         -- ^ computation to run first
@@ -348,7 +320,7 @@ finally :: IO a         -- ^ computation to run first
 a `finally` sequel =
   block (do
     r <- unblock a `onException` sequel
-    sequel
+    _ <- sequel
     return r
   )
 
@@ -367,7 +339,4 @@ a `finally` sequel =
 -- >   evaluate x = (return $! x) >>= return
 --
 evaluate :: a -> IO a
-evaluate a = IO $ \s -> case a `seq` () of () -> (# s, a #)
-        -- NB. can't write
-        --      a `seq` (# s, a #)
-        -- because we can't have an unboxed tuple as a function argument
+evaluate a = IO $ \s -> let !va = a in (# s, va #) -- NB. see #2273