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

Simon Marlow simonmar@microsoft.com
Fri, 1 Aug 2003 14:50:31 +0100


=20
> -- More comments, please. Bad names? Important missing functionality?
> -- Still unimplementable?

Basically I think this is good.  I think the naming should be rethought,
but that can be done later.

I wanted to float a generalisation of this scheme, though.  I'm
wondering whether it might be a good idea to make InputStream and
OutputStream into type classes, the advantage being that this makes
streams more extensible - one example is that memory-mapped files fit
neatly into this framework.  I already have 6 examples of things that
can have streams layered on top (or *are* streams), and there are almost
certainly more.

Here's some signatures for you to peruse:

class Stream s where
      closeStream	   :: s -> IO ()
      streamSetBuffering :: s -> BufferMode -> IO ()
      streamGetBuffering :: s -> IO BufferMode
      streamFlush	   :: s -> IO ()
      isEOS		   :: s -> IO Bool

class InputStream s where
      streamGet         :: s -> IO Word8
      streamReadBuffer  :: s -> Integer -> Buffer -> IO ()
      streamGetBuffer   :: s -> Integer -> IO ImmutableBuffer
      streamGetContents :: s -> IO [Word8]

class OutputStream s where
      streamPut         :: s -> Word8 -> IO ()
      streamPuts        :: s -> [Word8] -> IO ()
      streamWriteBuffer :: s -> Integer -> Buffer -> IO ()


-- Files in the filesystem, with access rights
data File
data FileInputStream  -- instance Stream, InputStream
data FileOutputStream -- instance Stream, OutputStream

-- Memory-mapped files
mapFile :: File -> FileOffset -> Integer -> MapMode -> IO MappedFile

data MappedFile
data MappedFileInputStream	-- instance Stream, InputStream
data MappedFileOutputStream	-- instance Stream, OutputStream

instance MArray MappedFile Word8 IO  -- so we can read/write it directly

mappedFileInputStream  :: MappedFile -> Integer -> Integer
	 -> IO MappedFileInputStream
mappedFileOutputStream :: MappedFile -> Integer -> Integer
	 -> IO MappedFileOutputStream

-- Pipes
data Pipe  -- a pipe with a read and a write end
instance Stream Pipe
instance InputStream Pipe
instance OutputStream Pipe
createPipe	 :: IO Pipe
closePipe	 :: Pipe -> IO ()

-- Streams from arrays:
data ArrayInputStream
instance InputStream ArrayInputStream
data ArrayOutputStream
instance OutputStream ArrayOutputStream
iarrayInputStream  :: (Ix i, IArray a Word8) =3D> a i Word8 -> i=20
	-> ArrayInputStream
marrayInputStream  :: (Ix i, MArray a Word8 IO) =3D> a i Word8 -> i
	-> ArrayInputStream
marrayOutputStream :: (Ix i, MArray a Word8 IO) =3D> a i Word8 -> i
	-> ArrayOutputStream

-- Sockets:
data Socket
instance Stream Socket
instance InputStream Socket
instance OutputStream Socket

-- URIs:
data URIStream
getURI :: URI -> IO URIStream
instance InputStream URIStream


Cheers,
	Simon