[project @ 2003-08-30 12:26:56 by ross]
authorross <unknown>
Sat, 30 Aug 2003 12:26:58 +0000 (12:26 +0000)
committerross <unknown>
Sat, 30 Aug 2003 12:26:58 +0000 (12:26 +0000)
docs for System.IO.Error

GHC/Exception.lhs
GHC/IOBase.lhs
Prelude.hs
System/IO/Error.hs

index a98ca19..08f5e97 100644 (file)
@@ -47,6 +47,24 @@ have to work around that in the definition of catchException below).
 catchException :: IO a -> (Exception -> IO a) -> IO a
 catchException (IO m) k =  IO $ \s -> catch# m (\ex -> unIO (k ex)) s
 
+-- | The 'catch' function establishes a handler that receives any 'IOError'
+-- raised in the action protected by 'catch'.  An 'IOError' is caught by
+-- the most recent handler established by 'catch'.  These handlers are
+-- not selective: all 'IOError's are caught.  Exception propagation
+-- must be explicitly provided in a handler by re-raising any unwanted
+-- exceptions.  For example, in
+--
+-- > f = catch g (\e -> if IO.isEOFError e then return [] else ioError e)
+--
+-- the function @f@ returns @[]@ when an end-of-file exception
+-- (cf. 'System.IO.Error.isEOFError') occurs in @g@; otherwise, the
+-- exception is propagated to the next outer handler.
+--
+-- When an exception propagates outside the main program, the Haskell
+-- system prints the associated 'IOError' value and exits the program.
+--
+-- Non-I\/O exceptions are not caught by this variant; to catch all
+-- exceptions, use 'Control.Exception.catch' from "Control.Exception".
 catch           :: IO a -> (IOError -> IO a) -> IO a 
 catch m k      =  catchException m handler
   where handler (IOException err)   = k err
index 84a2d84..c25c69e 100644 (file)
@@ -743,13 +743,18 @@ throwIO err       =  IO $ raiseIO# err
 ioException    :: IOException -> IO a
 ioException err =  IO $ raiseIO# (IOException err)
 
+-- | Raise an 'IOError' in the 'IO' monad.
 ioError         :: IOError -> IO a 
 ioError                =  ioException
 
 -- ---------------------------------------------------------------------------
 -- IOError type
 
--- | The Haskell 98 type for exceptions in the @IO@ monad.
+-- | The Haskell 98 type for exceptions in the 'IO' monad.
+-- Any I\/O operation may raise an 'IOError' instead of returning a result.
+-- For a more general type of exception, including also those that arise
+-- in pure code, see 'Control.Exception.Exception'.
+--
 -- In Haskell 98, this is an opaque type.
 type IOError = IOException
 
@@ -771,6 +776,7 @@ instance Eq IOException where
   (IOError h1 e1 loc1 str1 fn1) == (IOError h2 e2 loc2 str2 fn2) = 
     e1==e2 && str1==str2 && h1==h2 && loc1==loc2 && fn1==fn2
 
+-- | An abstract type that contains a value for each variant of 'IOError'.
 data IOErrorType
   -- Haskell 98:
   = AlreadyExists
@@ -826,6 +832,14 @@ instance Show IOErrorType where
       UnsupportedOperation -> "unsupported operation"
       DynIOError{}      -> "unknown IO error"
 
+-- | Construct an 'IOError' value with a string describing the error.
+-- The 'fail' method of the 'IO' instance of the 'Monad' class raises a
+-- 'userError', thus:
+--
+-- > instance Monad IO where 
+-- >   ...
+-- >   fail s = ioError (userError s)
+--
 userError       :: String  -> IOError
 userError str  =  IOError Nothing UserError "" str Nothing
 
index 31aa6b6..7ad6355 100644 (file)
@@ -75,14 +75,24 @@ module Prelude (
     reads, shows, read, lex, 
     showChar, showString, readParen, showParen,
     
-    -- * Simple I\/O operations
-    ioError, userError, catch,
-    FilePath, IOError,
+    -- * Basic Input and output
+    -- ** Simple I\/O operations
+    -- All I/O functions defined here are character oriented.  The
+    -- treatment of the newline character will vary on different systems.
+    -- For example, two characters of input, return and linefeed, may
+    -- read as a single newline character.  These functions cannot be
+    -- used portably for binary I/O.
+    -- *** Output functions
     putChar,
     putStr, putStrLn, print,
+    -- *** Input functions
     getChar,
     getLine, getContents, interact,
+    -- *** Files
+    FilePath,
     readFile, writeFile, appendFile, readIO, readLn,
+    -- ** Exception handling in the I\/O monad
+    IOError, ioError, userError, catch,
 
     -- * Monads
     Monad((>>=), (>>), return, fail),
index 14e29fb..7250ef4 100644 (file)
 -----------------------------------------------------------------------------
 
 module System.IO.Error (
-    IOError,                   -- abstract
-    IOErrorType,               -- abstract
 
-    catch,                     -- :: IO a -> (IOError -> IO a) -> IO a
-    try,                       -- :: IO a -> IO (Either IOError a)
+    -- * I\/O errors
+    IOError,                   -- = IOException
 
-    ioError,                   -- :: IOError -> IO a
     userError,                 -- :: String  -> IOError
 
 #ifndef __NHC__
@@ -30,10 +27,36 @@ module System.IO.Error (
 
     annotateIOError,           -- :: IOError -> String -> Maybe Handle
                                --    -> Maybe FilePath -> IOError
+#endif
 
-    modifyIOError,             -- :: (IOError -> IOError) -> IO a -> IO a
+    -- ** Classifying I\/O errors
+    isAlreadyExistsError,      -- :: IOError -> Bool
+    isDoesNotExistError,
+    isAlreadyInUseError,
+    isFullError, 
+    isEOFError,
+    isIllegalOperation, 
+    isPermissionError,
+    isUserError,
+
+    -- ** Attributes of I\/O errors
+#ifndef __NHC__
+    ioeGetErrorType,           -- :: IOError -> IOErrorType
+#endif
+    ioeGetErrorString,         -- :: IOError -> String
+    ioeGetHandle,              -- :: IOError -> Maybe Handle
+    ioeGetFileName,            -- :: IOError -> Maybe FilePath
+
+#ifndef __NHC__
+    ioeSetErrorType,           -- :: IOError -> IOErrorType -> IOError
+    ioeSetErrorString,         -- :: IOError -> String -> IOError
+    ioeSetHandle,              -- :: IOError -> Handle -> IOError
+    ioeSetFileName,            -- :: IOError -> FilePath -> IOError
 #endif
 
+    -- * Types of I\/O error
+    IOErrorType,               -- abstract
+
     alreadyExistsErrorType,    -- :: IOErrorType
     doesNotExistErrorType,
     alreadyInUseErrorType,
@@ -43,6 +66,7 @@ module System.IO.Error (
     permissionErrorType,
     userErrorType,
 
+    -- ** 'IOErrorType' predicates
     isAlreadyExistsErrorType,  -- :: IOErrorType -> Bool
     isDoesNotExistErrorType,
     isAlreadyInUseErrorType,
@@ -52,27 +76,15 @@ module System.IO.Error (
     isPermissionErrorType,
     isUserErrorType, 
 
-    isAlreadyExistsError,      -- :: IOError -> Bool
-    isDoesNotExistError,
-    isAlreadyInUseError,
-    isFullError, 
-    isEOFError,
-    isIllegalOperation, 
-    isPermissionError,
-    isUserError,
+    -- * Throwing and catching I\/O errors
 
-#ifndef __NHC__
-    ioeGetErrorType,           -- :: IOError -> IOErrorType
-#endif
-    ioeGetErrorString,         -- :: IOError -> String
-    ioeGetHandle,              -- :: IOError -> Maybe Handle
-    ioeGetFileName,            -- :: IOError -> Maybe FilePath
+    ioError,                   -- :: IOError -> IO a
+
+    catch,                     -- :: IO a -> (IOError -> IO a) -> IO a
+    try,                       -- :: IO a -> IO (Either IOError a)
 
 #ifndef __NHC__
-    ioeSetErrorType,           -- :: IOError -> IOErrorType -> IOError
-    ioeSetErrorString,         -- :: IOError -> String -> IOError
-    ioeSetHandle,              -- :: IOError -> Handle -> IOError
-    ioeSetFileName,            -- :: IOError -> FilePath -> IOError
+    modifyIOError,             -- :: (IOError -> IOError) -> IO a -> IO a
 #endif
   ) where
 
@@ -112,10 +124,11 @@ import IO
 --import Control.Monad (MonadPlus(mplus))
 #endif
 
--- | The construct @try comp@ exposes IO errors which occur within a
+-- | The construct 'try' @comp@ exposes IO errors which occur within a
 -- computation, and which are not fully handled.
--- Other exceptions are not caught by this variant;
--- to catch all exceptions, use @try@ from "Control.Exception".
+--
+-- Non-I\/O exceptions are not caught by this variant; to catch all
+-- exceptions, use 'Control.Exception.try' from "Control.Exception".
 
 #ifndef __NHC__
 try            :: IO a -> IO (Either IOError a)
@@ -128,6 +141,10 @@ try f          =  catch (do r <- f
 -- -----------------------------------------------------------------------------
 -- Constructing an IOError
 
+-- | Construct an 'IOError' of the given type where the second argument
+-- describes the error location and the third and fourth argument
+-- contain the file handle and file path of the file involved in the
+-- error if applicable.
 mkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath -> IOError
 mkIOError t location maybe_hdl maybe_filename =
                IOError{ ioe_type = t, 
@@ -157,17 +174,50 @@ mkIOError t         location maybe_hdl maybe_filename =
 -- -----------------------------------------------------------------------------
 -- IOErrorType
 
-isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError,
- isFullError, isEOFError, isIllegalOperation, isPermissionError,
- isUserError :: IOError -> Bool
-
+-- | An error indicating that an 'IO' operation failed because
+-- one of its arguments already exists.
+isAlreadyExistsError :: IOError -> Bool
 isAlreadyExistsError = isAlreadyExistsErrorType    . ioeGetErrorType
+
+-- | An error indicating that an 'IO' operation failed because
+-- one of its arguments does not exist.
+isDoesNotExistError :: IOError -> Bool
 isDoesNotExistError  = isDoesNotExistErrorType     . ioeGetErrorType
+
+-- | An error indicating that an 'IO' operation failed because
+-- one of its arguments is a single-use resource, which is already
+-- being used (for example, opening the same file twice for writing
+-- might give this error).
+isAlreadyInUseError :: IOError -> Bool
 isAlreadyInUseError  = isAlreadyInUseErrorType     . ioeGetErrorType
+
+-- | An error indicating that an 'IO' operation failed because
+-- the device is full.
+isFullError         :: IOError -> Bool
 isFullError          = isFullErrorType             . ioeGetErrorType
+
+-- | An error indicating that an 'IO' operation failed because
+-- the end of file has been reached.
+isEOFError          :: IOError -> Bool
 isEOFError           = isEOFErrorType              . ioeGetErrorType
+
+-- | An error indicating that an 'IO' operation failed because
+-- the operation was not possible.
+-- Any computation which returns an 'IO' result may fail with
+-- 'isIllegalOperation'.  In some cases, an implementation will not be
+-- able to distinguish between the possible error causes.  In this case
+-- it should fail with 'isIllegalOperation'.
+isIllegalOperation  :: IOError -> Bool
 isIllegalOperation   = isIllegalOperationErrorType . ioeGetErrorType
+
+-- | An error indicating that an 'IO' operation failed because
+-- the user does not have sufficient operating system privilege
+-- to perform that operation.
+isPermissionError   :: IOError -> Bool
 isPermissionError    = isPermissionErrorType       . ioeGetErrorType
+
+-- | A programmer-defined error value constructed using 'userError'.
+isUserError         :: IOError -> Bool
 isUserError          = isUserErrorType             . ioeGetErrorType
 #endif /* __NHC__ */
 
@@ -180,47 +230,88 @@ data IOErrorType = AlreadyExists | NoSuchThing | ResourceBusy
                 | PermissionDenied | UserError
 #endif
 
-alreadyExistsErrorType, doesNotExistErrorType, alreadyInUseErrorType,
- fullErrorType, eofErrorType, illegalOperationErrorType,
- permissionErrorType, userErrorType :: IOErrorType
-
+-- | I\/O error where the operation failed because one of its arguments
+-- already exists.
+alreadyExistsErrorType   :: IOErrorType
 alreadyExistsErrorType    = AlreadyExists
+
+-- | I\/O error where the operation failed because one of its arguments
+-- does not exist.
+doesNotExistErrorType    :: IOErrorType
 doesNotExistErrorType     = NoSuchThing
+
+-- | I\/O error where the operation failed because one of its arguments
+-- is a single-use resource, which is already being used.
+alreadyInUseErrorType    :: IOErrorType
 alreadyInUseErrorType     = ResourceBusy
+
+-- | I\/O error where the operation failed because the device is full.
+fullErrorType            :: IOErrorType
 fullErrorType             = ResourceExhausted
+
+-- | I\/O error where the operation failed because the end of file has
+-- been reached.
+eofErrorType             :: IOErrorType
 eofErrorType              = EOF
+
+-- | I\/O error where the operation is not possible.
+illegalOperationErrorType :: IOErrorType
 illegalOperationErrorType = IllegalOperation
+
+-- | I\/O error where the operation failed because the user does not
+-- have sufficient operating system privilege to perform that operation.
+permissionErrorType      :: IOErrorType
 permissionErrorType       = PermissionDenied
+
+-- | I\/O error that is programmer-defined.
+userErrorType           :: IOErrorType
 userErrorType            = UserError
 
 -- -----------------------------------------------------------------------------
 -- IOErrorType predicates
 
-isAlreadyExistsErrorType, isDoesNotExistErrorType, isAlreadyInUseErrorType,
-  isFullErrorType, isEOFErrorType, isIllegalOperationErrorType, 
-  isPermissionErrorType, isUserErrorType :: IOErrorType -> Bool
-
+-- | I\/O error where the operation failed because one of its arguments
+-- already exists.
+isAlreadyExistsErrorType :: IOErrorType -> Bool
 isAlreadyExistsErrorType AlreadyExists = True
 isAlreadyExistsErrorType _ = False
 
+-- | I\/O error where the operation failed because one of its arguments
+-- does not exist.
+isDoesNotExistErrorType :: IOErrorType -> Bool
 isDoesNotExistErrorType NoSuchThing = True
 isDoesNotExistErrorType _ = False
 
+-- | I\/O error where the operation failed because one of its arguments
+-- is a single-use resource, which is already being used.
+isAlreadyInUseErrorType :: IOErrorType -> Bool
 isAlreadyInUseErrorType ResourceBusy = True
 isAlreadyInUseErrorType _ = False
 
+-- | I\/O error where the operation failed because the device is full.
+isFullErrorType :: IOErrorType -> Bool
 isFullErrorType ResourceExhausted = True
 isFullErrorType _ = False
 
+-- | I\/O error where the operation failed because the end of file has
+-- been reached.
+isEOFErrorType :: IOErrorType -> Bool
 isEOFErrorType EOF = True
 isEOFErrorType _ = False
 
+-- | I\/O error where the operation is not possible.
+isIllegalOperationErrorType :: IOErrorType -> Bool
 isIllegalOperationErrorType IllegalOperation = True
 isIllegalOperationErrorType _ = False
 
+-- | I\/O error where the operation failed because the user does not
+-- have sufficient operating system privilege to perform that operation.
+isPermissionErrorType :: IOErrorType -> Bool
 isPermissionErrorType PermissionDenied = True
 isPermissionErrorType _ = False
 
+-- | I\/O error that is programmer-defined.
+isUserErrorType :: IOErrorType -> Bool
 isUserErrorType UserError = True
 isUserErrorType _ = False
 
@@ -253,12 +344,17 @@ ioeSetErrorString ioe str      = ioe{ ioe_description = str }
 ioeSetHandle      ioe hdl      = ioe{ ioe_handle = Just hdl }
 ioeSetFileName    ioe filename = ioe{ ioe_filename = Just filename }
 
+-- | Catch any 'IOError' that occurs in the computation and throw a
+-- modified version.
 modifyIOError :: (IOError -> IOError) -> IO a -> IO a
 modifyIOError f io = catch io (\e -> ioError (f e))
 
 -- -----------------------------------------------------------------------------
 -- annotating an IOError
 
+-- | Adds a location description and maybe a file path and file handle
+-- to an 'IOError'.  If any of the file handle or file path is not given
+-- the corresponding value in the 'IOError' remains unaltered.
 annotateIOError :: IOError 
               -> String 
               -> Maybe Handle