Raw I/O library proposal, second (more pragmatic) draft

Ashley Yakeley ashley@semantic.org
Wed, 06 Aug 2003 15:14:23 -0700

In article <SMARTHOSTgwrVV72XSB00019414@SMARTHOST.microsoft.com>,
 "Simon Marlow" <simonmar@microsoft.com> wrote:

> fileRead    :: File -> FileOffset -> Integer -> Buffer -> IO ()
> fileGet     :: File -> FileOffset -> Integer -> IO ImmutableBuffer

Should fileRead return the number of bytes read, in case of asking for 
more bytes than are in the file? With fileGet you can simply look at the 
size of the return buffer.

> 	-- | Flushes the buffer to the operating system for an output
> 	-- buffer, or discards buffered data for an input buffer.
> 	flush	   	:: s -> IO ()

Those are two very different things, aren't they? The first pushes data 
along the pipe (rather than discarding it). The second discards data, 
equivalent to calling streamGetAvailable and ignoring the result.

My preference would be to move flush to OutputStream and, if necessary, 
add a streamDiscardAvailable. But I can't offhand think of any use for 
streamDiscardAvailable and it already can be done with 

> 	-- | Flushes the buffered data as far as possible, even to the
> 	-- physical media if it can.  It returns 'True' if the data
> 	-- has definitely been flushed as far as it can go: to the 
> 	-- disk for a disk file, to the screen for a terminal, and so on.
> 	sync		:: s -> IO Bool

This one seems to be output only. Would it ever be meaningful to call 
sync on an input-stream?

> class InputStream s where
> class OutputStream s where

Presumably you wanted Stream superclasses for these?

>     streamGet      :: s -> IO Word8

What does this return after the last byte has been read? What does this 
return for an empty file?

>     streamReadBuffer   :: s -> Integer -> Buffer -> IO ()
>     streamGetBuffer    :: s -> Integer -> IO ImmutableBuffer

Same issue as fileRead/fileGet.

>  Parameterise InputStream over the element type too, so we can
>  combine InputStream and TextInputStream?  NO: uses multiparam type
>  classes.

Unless of course your stream type is a type constructor:

class InputStream s where
  streamGet :: s m e -> m e

Ashley Yakeley, Seattle WA