[project @ 2003-08-31 18:41:28 by ross]
[ghc-base.git] / GHC / IOBase.lhs
index cbad7db..be727df 100644 (file)
@@ -220,6 +220,34 @@ instance Eq (MVar a) where
 -- Note: when a Handle is garbage collected, we want to flush its buffer
 -- and close the OS file handle, so as to free up a (precious) resource.
 
+-- | Haskell defines operations to read and write characters from and to files,
+-- represented by values of type @Handle@.  Each value of this type is a
+-- /handle/: a record used by the Haskell run-time system to /manage/ I\/O
+-- with file system objects.  A handle has at least the following properties:
+-- 
+--  * whether it manages input or output or both;
+--
+--  * whether it is /open/, /closed/ or /semi-closed/;
+--
+--  * whether the object is seekable;
+--
+--  * whether buffering is disabled, or enabled on a line or block basis;
+--
+--  * a buffer (whose length may be zero).
+--
+-- Most handles will also have a current I\/O position indicating where the next
+-- input or output operation will occur.  A handle is /readable/ if it
+-- manages only input or both input and output; likewise, it is /writable/ if
+-- it manages only output or both input and output.  A handle is /open/ when
+-- first allocated.
+-- Once it is closed it can no longer be used for either input or output,
+-- though an implementation cannot re-use its storage while references
+-- remain to it.  Handles are in the 'Show' and 'Eq' classes.  The string
+-- produced by showing a handle is system dependent; it should include
+-- enough information to identify the handle for debugging.  A handle is
+-- equal according to '==' only to itself; no attempt
+-- is made to compare the internal state of different handles for equality.
+
 data Handle 
   = FileHandle                         -- A normal handle to a file
        FilePath                        -- the file (invariant)
@@ -340,53 +368,63 @@ isWritableHandleType WriteHandle     = True
 isWritableHandleType ReadWriteHandle = True
 isWritableHandleType _              = False
 
--- File names are specified using @FilePath@, a OS-dependent
--- string that (hopefully, I guess) maps to an accessible file/object.
+-- | File and directory names are values of type 'String', whose precise
+-- meaning is operating system dependent. Files can be opened, yielding a
+-- handle which can then be used to operate on the contents of that file.
 
 type FilePath = String
 
 -- ---------------------------------------------------------------------------
 -- Buffering modes
 
--- Three kinds of buffering are supported: line-buffering, 
+-- | Three kinds of buffering are supported: line-buffering, 
 -- block-buffering or no-buffering.  These modes have the following
--- effects. For output, items are written out from the internal
--- buffer according to the buffer mode:
+-- effects. For output, items are written out, or /flushed/,
+-- from the internal buffer according to the buffer mode:
 --
--- o line-buffering  the entire output buffer is written
---   out whenever a newline is output, the output buffer overflows, 
---   a flush is issued, or the handle is closed.
+--  * /line-buffering/: the entire output buffer is flushed
+--    whenever a newline is output, the buffer overflows, 
+--    a 'System.IO.hFlush' is issued, or the handle is closed.
 --
--- o block-buffering the entire output buffer is written out whenever 
---   it overflows, a flush is issued, or the handle
---   is closed.
+--  * /block-buffering/: the entire buffer is written out whenever it
+--    overflows, a 'System.IO.hFlush' is issued, or the handle is closed.
 --
--- o no-buffering output is written immediately, and never stored
---   in the output buffer.
+--  * /no-buffering/: output is written immediately, and never stored
+--    in the buffer.
 --
+-- An implementation is free to flush the buffer more frequently,
+-- but not less frequently, than specified above.
 -- The output buffer is emptied as soon as it has been written out.
-
+--
 -- Similarly, input occurs according to the buffer mode for handle {\em hdl}.
-
--- o line-buffering when the input buffer for the handle is not empty,
---   the next item is obtained from the buffer;
---   otherwise, when the input buffer is empty,
---   characters up to and including the next newline
---   character are read into the buffer.  No characters
---   are available until the newline character is
---   available.
 --
--- o block-buffering when the input buffer for the handle becomes empty,
---   the next block of data is read into this buffer.
+--  * /line-buffering/: when the buffer for the handle is not empty,
+--    the next item is obtained from the buffer; otherwise, when the
+--    buffer is empty, characters up to and including the next newline
+--    character are read into the buffer.  No characters are available
+--    until the newline character is available or the buffer is full.
 --
--- o no-buffering the next input item is read and returned.
-
+--  * /block-buffering/: when the buffer for the handle becomes empty,
+--    the next block of data is read into the buffer.
+--
+--  * /no-buffering/: the next input item is read and returned.
+--    The 'System.IO.hLookAhead' operation implies that even a no-buffered
+--    handle may require a one-character buffer.
+--
+-- The default buffering mode when a handle is opened is
+-- implementation-dependent and may depend on the file system object
+-- which is attached to that handle.
 -- For most implementations, physical files will normally be block-buffered 
--- and terminals will normally be line-buffered. (the IO interface provides
--- operations for changing the default buffering of a handle tho.)
+-- and terminals will normally be line-buffered.
 
 data BufferMode  
- = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
+ = NoBuffering -- ^ buffering is disabled if possible.
+ | LineBuffering
+               -- ^ line-buffering should be enabled if possible.
+ | BlockBuffering (Maybe Int)
+               -- ^ block-buffering should be enabled if possible.
+               -- The size of the buffer is @n@ items if the argument
+               -- is 'Just' @n@ and is otherwise implementation-dependent.
    deriving (Eq, Ord, Read, Show)
 
 -- ---------------------------------------------------------------------------
@@ -480,7 +518,8 @@ showHandle file = showString "{handle: " . showString file . showString "}"
 -- |The type of exceptions.  Every kind of system-generated exception
 -- has a constructor in the 'Exception' type, and values of other
 -- types may be injected into 'Exception' by coercing them to
--- 'Dynamic' (see the section on Dynamic Exceptions: "Control.Exception\#DynamicExceptions").
+-- 'Data.Dynamic.Dynamic' (see the section on Dynamic Exceptions:
+-- "Control.Exception\#DynamicExceptions").
 data Exception
   = ArithException     ArithException
        -- ^Exceptions raised by arithmetic
@@ -499,8 +538,8 @@ data Exception
        -- ^Asynchronous exceptions (see section on Asynchronous Exceptions: "Control.Exception\#AsynchronousExceptions").
   | BlockedOnDeadMVar
        -- ^The current thread was executing a call to
-       -- 'takeMVar' that could never return, because there are no other
-       -- references to this 'MVar'.
+       -- 'Control.Concurrent.MVar.takeMVar' that could never return,
+       -- because there are no other references to this 'MVar'.
   | Deadlock
        -- ^There are no runnable threads, so the program is
        -- deadlocked.  The 'Deadlock' exception is
@@ -514,7 +553,7 @@ data Exception
   | ExitException      ExitCode
        -- ^The 'ExitException' exception is thrown by 'System.Exit.exitWith' (and
        -- 'System.Exit.exitFailure').  The 'ExitCode' argument is the value passed 
-       -- to 'System.exitWith'.  An unhandled 'ExitException' exception in the
+       -- to 'System.Exit.exitWith'.  An unhandled 'ExitException' exception in the
        -- main thread will cause the program to be terminated with the given 
        -- exit code.
   | IOException        IOException
@@ -582,7 +621,7 @@ data AsyncException
        --      * GHC currently does not throw 'HeapOverflow' exceptions.
   | ThreadKilled
        -- ^This exception is raised by another thread
-       -- calling 'killThread', or by the system
+       -- calling 'Control.Concurrent.killThread', or by the system
        -- if it needs to terminate the thread for some
        -- reason.
   deriving (Eq, Ord)
@@ -663,18 +702,17 @@ instance Eq Exception where
 -- -----------------------------------------------------------------------------
 -- The ExitCode type
 
--- The `ExitCode' type defines the exit codes that a program
--- can return.  `ExitSuccess' indicates successful termination;
--- and `ExitFailure code' indicates program failure
--- with value `code'.  The exact interpretation of `code'
--- is operating-system dependent.  In particular, some values of 
--- `code' may be prohibited (e.g. 0 on a POSIX-compliant system).
-
 -- We need it here because it is used in ExitException in the
 -- Exception datatype (above).
 
-data ExitCode = ExitSuccess | ExitFailure Int 
-                deriving (Eq, Ord, Read, Show)
+data ExitCode
+  = ExitSuccess        -- ^ indicates successful termination;
+  | ExitFailure Int
+               -- ^ indicates program failure with an exit code.
+               -- The exact interpretation of the code is
+               -- operating-system dependent.  In particular, some values
+               -- may be prohibited (e.g. 0 on a POSIX-compliant system).
+  deriving (Eq, Ord, Read, Show)
 
 -- --------------------------------------------------------------------------
 -- Primitive throw
@@ -705,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
 
@@ -733,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
@@ -788,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