-{-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# OPTIONS_GHC -XNoImplicitPrelude -funbox-strict-fields #-}
+{-# OPTIONS_GHC -XNoImplicitPrelude -funbox-strict-fields -XBangPatterns #-}
{-# OPTIONS_HADDOCK hide #-}
-----------------------------------------------------------------------------
-- |
-- #hide
module GHC.IO (
- IO(..), unIO, failIO, liftIO, bindIO, thenIO, returnIO,
+ IO(..), unIO, failIO, liftIO,
unsafePerformIO, unsafeInterleaveIO,
unsafeDupablePerformIO, unsafeDupableInterleaveIO,
noDuplicate,
--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)))
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,
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:
@
-- > 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