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 ioToST :: IO a -> ST RealWorld a
103 stToIO (ST m) = IO $ \ s -> case (m s) of STret new_s r -> IOok new_s r
105 ioToST (IO io) = ST $ \ s ->
107 IOok new_s a -> STret new_s a
108 IOfail new_s e -> error ("I/O Error (ioToST): " ++ showsPrec 0 e "\n")
111 %*********************************************************
113 \subsection{Utility functions}
115 %*********************************************************
117 I'm not sure why this little function is here...
120 fputs :: Addr{-FILE*-} -> String -> IO Bool
122 fputs stream [] = return True
124 fputs stream (c : cs)
125 = _ccall_ stg_putc c stream >> -- stg_putc expands to putc
126 fputs stream cs -- (just does some casting stream)
130 %*********************************************************
132 \subsection{Type @IOError@}
134 %*********************************************************
136 A value @IOError@ encode errors occurred in the @IO@ monad.
137 An @IOError@ records a more specific error type, a descriptive
138 string and maybe the handle that was used when the error was
144 (Maybe Handle) -- the handle used by the action flagging the
146 IOErrorType -- what it was.
147 String -- error type specific information.
151 = AlreadyExists | HardwareFault
152 | IllegalOperation | InappropriateType
153 | Interrupted | InvalidArgument
154 | NoSuchThing | OtherError
155 | PermissionDenied | ProtocolError
156 | ResourceBusy | ResourceExhausted
157 | ResourceVanished | SystemError
158 | TimeExpired | UnsatisfiedConstraints
159 | UnsupportedOperation | UserError
165 Predicates on IOError; little effort made on these so far...
169 isAlreadyExistsError (IOError _ AlreadyExists _) = True
170 isAlreadyExistsError _ = False
172 isAlreadyInUseError (IOError _ ResourceBusy _) = True
173 isAlreadyInUseError _ = False
175 isFullError (IOError _ ResourceExhausted _) = True
176 isFullError _ = False
178 isEOFError (IOError _ EOF _) = True
181 isIllegalOperation (IOError _ IllegalOperation _) = True
182 isIllegalOperation _ = False
184 isPermissionError (IOError _ PermissionDenied _) = True
185 isPermissionError _ = False
187 isDoesNotExistError (IOError _ NoSuchThing _) = True
188 isDoesNotExistError _ = False
190 isUserError (IOError _ UserError s) = Just s
191 isUserError _ = Nothing
197 instance Show IOError where
198 showsPrec p (IOError _ UserError s) rs =
201 showsPrec p (IOError _ EOF _) rs =
204 showsPrec p (IOError _ iot s) rs =
209 _ -> showString ": " $
214 The @String@ part of an @IOError@ is platform-dependent. However, to
215 provide a uniform mechanism for distinguishing among errors within
216 these broad categories, each platform-specific standard shall specify
217 the exact strings to be used for particular errors. For errors not
218 explicitly mentioned in the standard, any descriptive string may be
222 SOF & 4/96 & added argument to indicate function that flagged error
224 % Hmm..does these envs work?!...SOF
227 constructErrorAndFail :: String -> IO a
228 constructErrorAndFail call_site
229 = constructError call_site >>= \ io_error ->
234 This doesn't seem to be documented/spelled out anywhere,
237 The implementation of the IO prelude uses various C stubs
238 to do the actual interaction with the OS. The bandwidth
239 \tr{C<->Haskell} is somewhat limited, so the general strategy
240 for flaggging any errors (apart from possibly using the
241 return code of the external call), is to set the @ghc_errtype@
242 to a value that is one of the \tr{#define}s in @includes/error.h@.
243 @ghc_errstr@ holds a character string providing error-specific
247 constructError :: String -> IO IOError
248 constructError call_site =
249 _casm_ ``%r = ghc_errtype;'' >>= \ (I# errtype#) ->
250 _casm_ ``%r = ghc_errstr;'' >>= \ str ->
254 ERR_ALREADYEXISTS# -> AlreadyExists
255 ERR_HARDWAREFAULT# -> HardwareFault
256 ERR_ILLEGALOPERATION# -> IllegalOperation
257 ERR_INAPPROPRIATETYPE# -> InappropriateType
258 ERR_INTERRUPTED# -> Interrupted
259 ERR_INVALIDARGUMENT# -> InvalidArgument
260 ERR_NOSUCHTHING# -> NoSuchThing
261 ERR_OTHERERROR# -> OtherError
262 ERR_PERMISSIONDENIED# -> PermissionDenied
263 ERR_PROTOCOLERROR# -> ProtocolError
264 ERR_RESOURCEBUSY# -> ResourceBusy
265 ERR_RESOURCEEXHAUSTED# -> ResourceExhausted
266 ERR_RESOURCEVANISHED# -> ResourceVanished
267 ERR_SYSTEMERROR# -> SystemError
268 ERR_TIMEEXPIRED# -> TimeExpired
269 ERR_UNSATISFIEDCONSTRAINTS# -> UnsatisfiedConstraints
270 ERR_UNSUPPORTEDOPERATION# -> UnsupportedOperation
275 call_site ++ ':' : ' ' : unpackCString str ++
277 OtherError -> "(error code: " ++ show (I# errtype#) ++ ")"
280 return (IOError Nothing iot msg)
283 %*********************************************************
285 \subsection{Types @Handle@, @Handle__@}
287 %*********************************************************
289 The type for @Handle@ is defined rather than in @IOHandle@
290 module, as the @IOError@ type uses it..all operations over
291 a handles reside in @IOHandle@.
296 Sigh, the MVar ops in ConcBase depend on IO, the IO
297 representation here depend on MVars for handles (when
298 compiling a concurrent way). Break the cycle by having
299 the definition of MVars go here:
302 data MVar a = MVar (SynchVar# RealWorld a)
305 Double sigh - ForeignObj is needed here too to break a cycle.
307 data ForeignObj = ForeignObj ForeignObj# -- another one
309 #if defined(__CONCURRENT_HASKELL__)
310 type Handle = MVar Handle__
312 type Handle = MutableVar RealWorld Handle__
316 = ErrorHandle IOError
318 #ifndef __PARALLEL_HASKELL__
319 | SemiClosedHandle ForeignObj (Addr, Int)
320 | ReadHandle ForeignObj (Maybe BufferMode) Bool
321 | WriteHandle ForeignObj (Maybe BufferMode) Bool
322 | AppendHandle ForeignObj (Maybe BufferMode) Bool
323 | ReadWriteHandle ForeignObj (Maybe BufferMode) Bool
325 | SemiClosedHandle Addr (Addr, Int)
326 | ReadHandle Addr (Maybe BufferMode) Bool
327 | WriteHandle Addr (Maybe BufferMode) Bool
328 | AppendHandle Addr (Maybe BufferMode) Bool
329 | ReadWriteHandle Addr (Maybe BufferMode) Bool
332 -- Standard Instances as defined by the Report..
333 -- instance Eq Handle (defined in IO)
334 -- instance Show Handle ""
338 %*********************************************************
340 \subsection[BufferMode]{Buffering modes}
342 %*********************************************************
344 Three kinds of buffering are supported: line-buffering,
345 block-buffering or no-buffering. These modes have the following
346 effects. For output, items are written out from the internal
347 buffer according to the buffer mode:
350 \item[line-buffering] the entire output buffer is written
351 out whenever a newline is output, the output buffer overflows,
352 a flush is issued, or the handle is closed.
354 \item[block-buffering] the entire output buffer is written out whenever
355 it overflows, a flush is issued, or the handle
358 \item[no-buffering] output is written immediately, and never stored
359 in the output buffer.
362 The output buffer is emptied as soon as it has been written out.
364 Similarly, input occurs according to the buffer mode for handle {\em hdl}.
366 \item[line-buffering] when the input buffer for {\em hdl} is not empty,
367 the next item is obtained from the buffer;
368 otherwise, when the input buffer is empty,
369 characters up to and including the next newline
370 character are read into the buffer. No characters
371 are available until the newline character is
373 \item[block-buffering] when the input buffer for {\em hdl} becomes empty,
374 the next block of data is read into this buffer.
375 \item[no-buffering] the next input item is read and returned.
377 For most implementations, physical files will normally be block-buffered
378 and terminals will normally be line-buffered.
382 = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
383 deriving (Eq, Ord, {-ToDo: Read,-} Show)
388 performGC = _ccall_GC_ StgPerformGarbageCollection