2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[IOBase]{Module @IOBase@}
7 Definitions for the @IO@ monad and its friends. Everything is exported
8 concretely; the @IO@ module itself exports abstractly.
11 {-# OPTIONS -fno-implicit-prelude #-}
16 import {-# SOURCE #-} Error
21 import PackBase ( unpackCString )
23 import ArrBase ( ByteArray(..), MutableVar(..) )
29 %*********************************************************
31 \subsection{The @IO@ monad}
33 %*********************************************************
35 IO is no longer built on top of PrimIO (which used to be a specialised
36 version of the ST monad), instead it is now has its own type. This is
37 purely for efficiency purposes, since we get to remove several levels
38 of lifting in the type of the monad.
41 newtype IO a = IO (State# RealWorld -> IOResult a)
46 data IOResult a = IOok (State# RealWorld) a
47 | IOfail (State# RealWorld) IOError
49 instance Functor IO where
50 map f x = x >>= (return . f)
52 instance Monad IO where
56 m >> k = m >>= \ _ -> k
57 return x = IO $ \ s -> IOok s x
62 IOfail new_s err -> IOfail new_s err
63 IOok new_s a -> unIO (k a) new_s
65 fixIO :: (a -> IO a) -> IO a
66 -- not required but worth having around
76 fail :: IOError -> IO a
77 fail err = IO $ \ s -> IOfail s err
79 userError :: String -> IOError
80 userError str = IOError Nothing UserError str
82 catch :: IO a -> (IOError -> IO a) -> IO a
83 catch (IO m) k = IO $ \ s ->
85 IOok new_s a -> IOok new_s a
86 IOfail new_s e -> unIO (k e) new_s
88 instance Show (IO a) where
89 showsPrec p f = showString "<<IO action>>"
90 showList = showList__ (showsPrec 0)
93 %*********************************************************
95 \subsection{Coercions to @ST@}
97 %*********************************************************
100 stToIO :: ST RealWorld a -> IO a
101 stToIO (ST m) = IO $ \ s -> case (m s) of STret new_s r -> IOok new_s r
103 ioToST :: IO a -> ST RealWorld a
104 ioToST (IO io) = ST $ \ s ->
106 IOok new_s a -> STret new_s a
107 IOfail new_s e -> error ("I/O Error (ioToST): " ++ showsPrec 0 e "\n")
110 %*********************************************************
112 \subsection{Utility functions}
114 %*********************************************************
116 I'm not sure why this little function is here...
119 fputs :: Addr{-FILE*-} -> String -> IO Bool
121 fputs stream [] = return True
123 fputs stream (c : cs)
124 = _ccall_ stg_putc c stream >> -- stg_putc expands to putc
125 fputs stream cs -- (just does some casting stream)
129 %*********************************************************
131 \subsection{Type @IOError@}
133 %*********************************************************
135 A value @IOError@ encode errors occurred in the @IO@ monad.
136 An @IOError@ records a more specific error type, a descriptive
137 string and maybe the handle that was used when the error was
143 (Maybe Handle) -- the handle used by the action flagging the
145 IOErrorType -- what it was.
146 String -- error type specific information.
150 = AlreadyExists | HardwareFault
151 | IllegalOperation | InappropriateType
152 | Interrupted | InvalidArgument
153 | NoSuchThing | OtherError
154 | PermissionDenied | ProtocolError
155 | ResourceBusy | ResourceExhausted
156 | ResourceVanished | SystemError
157 | TimeExpired | UnsatisfiedConstraints
158 | UnsupportedOperation | UserError
164 Predicates on IOError; little effort made on these so far...
168 isAlreadyExistsError (IOError _ AlreadyExists _) = True
169 isAlreadyExistsError _ = False
171 isAlreadyInUseError (IOError _ ResourceBusy _) = True
172 isAlreadyInUseError _ = False
174 isFullError (IOError _ ResourceExhausted _) = True
175 isFullError _ = False
177 isEOFError (IOError _ EOF _) = True
180 isIllegalOperation (IOError _ IllegalOperation _) = True
181 isIllegalOperation _ = False
183 isPermissionError (IOError _ PermissionDenied _) = True
184 isPermissionError _ = False
186 isDoesNotExistError (IOError _ NoSuchThing _) = True
187 isDoesNotExistError _ = False
189 isUserError (IOError _ UserError s) = Just s
190 isUserError _ = Nothing
196 instance Show IOError where
197 showsPrec p (IOError _ UserError s) rs =
200 showsPrec p (IOError _ EOF _) rs =
203 showsPrec p (IOError _ iot s) rs =
208 _ -> showString ": " $
213 The @String@ part of an @IOError@ is platform-dependent. However, to
214 provide a uniform mechanism for distinguishing among errors within
215 these broad categories, each platform-specific standard shall specify
216 the exact strings to be used for particular errors. For errors not
217 explicitly mentioned in the standard, any descriptive string may be
221 SOF & 4/96 & added argument to indicate function that flagged error
223 % Hmm..does these envs work?!...SOF
226 constructErrorAndFail :: String -> IO a
227 constructErrorAndFail call_site
228 = constructError call_site >>= \ io_error ->
233 This doesn't seem to be documented/spelled out anywhere,
236 The implementation of the IO prelude uses various C stubs
237 to do the actual interaction with the OS. The bandwidth
238 \tr{C<->Haskell} is somewhat limited, so the general strategy
239 for flaggging any errors (apart from possibly using the
240 return code of the external call), is to set the @ghc_errtype@
241 to a value that is one of the \tr{#define}s in @includes/error.h@.
242 @ghc_errstr@ holds a character string providing error-specific
246 constructError :: String -> IO IOError
247 constructError call_site =
248 _casm_ ``%r = ghc_errtype;'' >>= \ (I# errtype#) ->
249 _casm_ ``%r = ghc_errstr;'' >>= \ str ->
253 ERR_ALREADYEXISTS# -> AlreadyExists
254 ERR_HARDWAREFAULT# -> HardwareFault
255 ERR_ILLEGALOPERATION# -> IllegalOperation
256 ERR_INAPPROPRIATETYPE# -> InappropriateType
257 ERR_INTERRUPTED# -> Interrupted
258 ERR_INVALIDARGUMENT# -> InvalidArgument
259 ERR_NOSUCHTHING# -> NoSuchThing
260 ERR_OTHERERROR# -> OtherError
261 ERR_PERMISSIONDENIED# -> PermissionDenied
262 ERR_PROTOCOLERROR# -> ProtocolError
263 ERR_RESOURCEBUSY# -> ResourceBusy
264 ERR_RESOURCEEXHAUSTED# -> ResourceExhausted
265 ERR_RESOURCEVANISHED# -> ResourceVanished
266 ERR_SYSTEMERROR# -> SystemError
267 ERR_TIMEEXPIRED# -> TimeExpired
268 ERR_UNSATISFIEDCONSTRAINTS# -> UnsatisfiedConstraints
269 ERR_UNSUPPORTEDOPERATION# -> UnsupportedOperation
274 call_site ++ ':' : ' ' : unpackCString str ++
276 OtherError -> "(error code: " ++ show (I# errtype#) ++ ")"
279 return (IOError Nothing iot msg)
282 %*********************************************************
284 \subsection{Types @Handle@, @Handle__@}
286 %*********************************************************
288 The type for @Handle@ is defined rather than in @IOHandle@
289 module, as the @IOError@ type uses it..all operations over
290 a handles reside in @IOHandle@.
295 Sigh, the MVar ops in ConcBase depend on IO, the IO
296 representation here depend on MVars for handles (when
297 compiling a concurrent way). Break the cycle by having
298 the definition of MVars go here:
301 data MVar a = MVar (SynchVar# RealWorld a)
304 Double sigh - ForeignObj is needed here too to break a cycle.
306 data ForeignObj = ForeignObj ForeignObj# -- another one
308 #if defined(__CONCURRENT_HASKELL__)
309 newtype Handle = Handle (MVar Handle__)
311 newtype Handle = Handle (MutableVar RealWorld Handle__)
315 = ErrorHandle IOError
317 #ifndef __PARALLEL_HASKELL__
318 | SemiClosedHandle ForeignObj (Addr, Int)
319 | ReadHandle ForeignObj (Maybe BufferMode) Bool
320 | WriteHandle ForeignObj (Maybe BufferMode) Bool
321 | AppendHandle ForeignObj (Maybe BufferMode) Bool
322 | ReadWriteHandle ForeignObj (Maybe BufferMode) Bool
324 | SemiClosedHandle Addr (Addr, Int)
325 | ReadHandle Addr (Maybe BufferMode) Bool
326 | WriteHandle Addr (Maybe BufferMode) Bool
327 | AppendHandle Addr (Maybe BufferMode) Bool
328 | ReadWriteHandle Addr (Maybe BufferMode) Bool
331 -- Standard Instances as defined by the Report..
332 -- instance Eq Handle (defined in IO)
333 -- instance Show Handle ""
337 %*********************************************************
339 \subsection[BufferMode]{Buffering modes}
341 %*********************************************************
343 Three kinds of buffering are supported: line-buffering,
344 block-buffering or no-buffering. These modes have the following
345 effects. For output, items are written out from the internal
346 buffer according to the buffer mode:
349 \item[line-buffering] the entire output buffer is written
350 out whenever a newline is output, the output buffer overflows,
351 a flush is issued, or the handle is closed.
353 \item[block-buffering] the entire output buffer is written out whenever
354 it overflows, a flush is issued, or the handle
357 \item[no-buffering] output is written immediately, and never stored
358 in the output buffer.
361 The output buffer is emptied as soon as it has been written out.
363 Similarly, input occurs according to the buffer mode for handle {\em hdl}.
365 \item[line-buffering] when the input buffer for {\em hdl} is not empty,
366 the next item is obtained from the buffer;
367 otherwise, when the input buffer is empty,
368 characters up to and including the next newline
369 character are read into the buffer. No characters
370 are available until the newline character is
372 \item[block-buffering] when the input buffer for {\em hdl} becomes empty,
373 the next block of data is read into this buffer.
374 \item[no-buffering] the next input item is read and returned.
376 For most implementations, physical files will normally be block-buffered
377 and terminals will normally be line-buffered.
381 = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
382 deriving (Eq, Ord, Show)
383 {- Read instance defined in IO. -}
389 performGC = _ccall_GC_ StgPerformGarbageCollection