2 % (c) The AQUA Project, Glasgow University, 1994-1996
4 \section[IOExts]{Module @IOExts@}
6 @IOExts@ provides useful functionality that fall outside the
7 standard Haskell IO interface. Expect the contents of IOExts
8 to be the same for Hugs and GHC (same goes for any other
9 Hugs/GHC extension libraries, unless a function/type is
10 explicitly flagged as being implementation specific
14 {-# OPTIONS -fno-implicit-prelude #-}
21 , IORef -- instance of: Eq
28 , IOArray -- instance of: Eq
62 , freeHaskellFunctionPtr
76 import PrelHandle ( openFileEx, IOModeEx(..),
77 hSetEcho, hGetEcho, getHandleFd
85 import IO ( hPutStr, hPutChar )
86 import PrelAddr ( Addr )
90 unsafePtrEq :: a -> a -> Bool
93 unsafePtrEq = primReallyUnsafePtrEquality
96 case reallyUnsafePtrEquality# a b of
103 newIORef :: a -> IO (IORef a)
104 readIORef :: IORef a -> IO a
105 writeIORef :: IORef a -> a -> IO ()
108 type IORef a = STRef RealWorld a
110 readIORef = readSTRef
111 writeIORef = writeSTRef
113 newtype IORef a = IORef (MutableVar RealWorld a)
116 newIORef v = stToIO (newVar v) >>= \ var -> return (IORef var)
117 readIORef (IORef var) = stToIO (readVar var)
118 writeIORef (IORef var) v = stToIO (writeVar var v)
121 mkWeakIORef :: IORef a -> IO () -> IO (Weak (IORef a))
122 mkWeakIORef r@(IORef (MutableVar r#)) f = IO $ \s ->
123 case mkWeak# r# r f s of (# s1, w #) -> (# s1, Weak w #)
127 newIOArray :: Ix ix => (ix,ix) -> elt -> IO (IOArray ix elt)
128 boundsIOArray :: Ix ix => IOArray ix elt -> (ix, ix)
129 readIOArray :: Ix ix => IOArray ix elt -> ix -> IO elt
130 writeIOArray :: Ix ix => IOArray ix elt -> ix -> elt -> IO ()
131 freezeIOArray :: Ix ix => IOArray ix elt -> IO (Array ix elt)
132 thawIOArray :: Ix ix => Array ix elt -> IO (IOArray ix elt)
134 unsafeFreezeIOArray :: Ix ix => IOArray ix elt -> IO (Array ix elt)
135 unsafeThawIOArray :: Ix ix => Array ix elt -> IO (IOArray ix elt)
139 type IOArray ix elt = STArray RealWorld ix elt
140 newIOArray = newSTArray
141 boundsIOArray = boundsSTArray
142 readIOArray = readSTArray
143 writeIOArray = writeSTArray
144 freezeIOArray = freezeSTArray
145 thawIOArray = thawSTArray
147 newtype IOArray ix elt = IOArray (MutableArray RealWorld ix elt)
151 stToIO (newArray ixs elt) >>= \arr ->
154 boundsIOArray (IOArray arr) = boundsOfArray arr
156 readIOArray (IOArray arr) ix = stToIO (readArray arr ix)
158 writeIOArray (IOArray arr) ix elt = stToIO (writeArray arr ix elt)
160 freezeIOArray (IOArray arr) = stToIO (freezeArray arr)
163 marr <- stToIO (thawArray arr)
164 return (IOArray marr)
166 unsafeFreezeIOArray (IOArray arr) = stToIO (unsafeFreezeArray arr)
167 unsafeThawIOArray arr = do
168 marr <- stToIO (unsafeThawArray arr)
169 return (IOArray marr)
174 {-# NOINLINE trace #-}
175 trace :: String -> a -> a
177 trace string expr = unsafePerformIO $ do
181 trace string expr = unsafePerformIO $ do
182 fd <- getHandleFd stderr
183 hPutStr stderr string
185 _ccall_ PostTraceHook fd
190 Not something you want to call normally, but useful
191 in the cases where you do want to flush stuff out of
192 the heap or make sure you've got room enough
198 performGC = _ccall_GC_ performGC
202 When using 'foreign export dynamic' to dress up a Haskell
203 IO action to look like a C function pointer, a little bit
204 of memory is allocated (along with a stable pointer to
205 the Haskell IO action). When done with the C function
206 pointer, you'll need to call @freeHaskellFunctionPtr()@ to
207 let go of these resources - here's the Haskell wrapper for
208 that RTS entry point, should you want to free it from
212 foreign import ccall "freeHaskellFunctionPtr"
213 freeHaskellFunctionPtr :: Addr -> IO ()
219 Support for redirecting I/O on a handle to another for the
220 duration of an IO action. To re-route a handle, it is first
221 flushed, followed by replacing its innards (i.e., FILE_OBJECT)
222 with that of the other. This happens before and after the
225 If the action raises an exception, the handle is replaced back
226 to its old contents, but without flushing it first - as this
227 may provoke exceptions. Notice that the action may perform
228 I/O on either Handle, with the result that the I/O is interleaved.
229 (Why you would want to do this, is a completely different matter.)
231 ToDo: probably want to restrict what kind of handles can be
232 replaced with another - i.e., don't want to be able to replace
233 a writeable handle with a readable one.
236 withHandleFor :: Handle
240 withHandleFor h1 h2 act = do
246 h2_fo <- withHandle h2 $ \ h2_ -> return (h2_{haFO__=h1_fo}, haFO__ h2_)
247 catch (act >>= \ x -> hFlush h2 >> setFO h2 h2_fo >> return x)
248 (\ err -> setFO h2 h2_fo >> ioError err)
251 withHandle h $ \ h_ -> return (h_{haFO__=fo}, ())
254 wantRWHandle "withHandleFor" h $ \ h_ ->
259 Derived @withHandleFor@ combinators and, at the moment, these
260 are exported from @IOExts@ and not @withHandleFor@ itself.
263 withStdin h a = withHandleFor h stdin a
264 withStdout h a = withHandleFor h stdout a
265 withStderr h a = withHandleFor h stderr a