Input/Output in SML
Table of Contents
1. Introduction/Overview
I'm curious about the implementation details of input/output in Haskell and Standard ML, specifically how they compare to each other.
The Standard ML input/output seems to be specified in the Standard Basis library.
1.1. Observation
There seems to be no adequate way to formally specify input/output. Consequently, this is the only source of impurity which does not appear in the formal definition of Standard ML.
I also do not believe there is any adequate way to reason about IO.
2. Haskell
Haskell's IO Monad works with an abstraction called "handles". They are defined as (stripping back to bare bones):
data Handle = FileHandle FilePath !(MVar Handle__) | DuplexHandle FilePath !(MVar Handle__) !(MVar Handle__) data Handle__ = Handle__ { haFD :: !FD haType :: HandleType haIsBin :: Bool haIsStream :: Bool haBufferMode :: BufferMode haBuffer :: !(IORef Buffer) haBuffers :: !(IORef BufferList) haOtherSide :: (Maybe (MVar Handle__)) }
Then openFile :: FilePath -> IOMode -> IO Handle
creates a new IO
monad wrapping around any IO computations involving the given file.
Roughly, a Handle
is approximately equivalent to a union of a Reader
and Writer
in Standard ML. Instead of file descriptors, Standard ML
uses OS.IO.iodesc
for a platform-independent way to describe "files".
Then Haskell's IO roughly corresponds to the TextIO
module in Standard
ML, but in a monadic fashion.