IO Monad - SML
Table of Contents
1. Introduction
We can construct the IO Monad in Standard ML, which has been done in Gordon's PhD thesis. There the construction uses an abstract type:
infix 1 >> >>= abstype 'a Job = JOB of unit -> 'a with (* exec : 'a Job -> 'a *) fun exec (JOB f) = f () (* return : 'a -> 'a Job *) fun return x = JOB (fn _ => x) (* (>>=) : 'a Job * ('a -> 'b Job) -> 'b Job *) fun (JOB f) >>= q = JOB (fn _ => exec (q (f ()))) (* getStr : int -> TextIO.vector Job *) fun getStr n = JOB (fn _ => TextIO.inputN(TextIO.stdIn, n)) (* putStr : string -> unit Job *) fun putStr s = JOB (fn _ => print s) end (* (>>) : 'a Job * 'b Job -> 'b Job *) fun p >> q = p >>= (fn _ => q); (* gettingLine : string -> string Job *) fun gettingLine s = getStr 1 >>= (fn c => if c = "\n" then return(s) else gettingLine (s^c)); (* getLine : string Job *) val getLine = gettingLine ""; val main : unit Job = putStr "First name: " >> getLine >>= (fn first => putStr "Second name: " >> getLine >>= (fn second => putStr ("Hello "^first^" "^second^"\n"))); (* exec main; *)
2. Using Modules
We can encode the IO Monad using SML's Module system. The signature for a Monad would be:
signature MONAD = sig type 'a m; val return : 'a -> 'a m; val bind : 'a m -> ('a -> 'b m) -> 'b m; end;
The IO Monad requires a few more public-facing methods.
signature IO_MONAD = sig include MONAD; val exec : 'a m -> 'a; val getStr : int -> TextIO.vector m; val putStr : string -> unit m; end;
Observe we just switched the Job
constructor to m
. The
implementation details are straightforward.
3. References
- Andrew Gordon,
"Functional Programming and Input/Output".
Ph.D. Thesis, Cambridge, 1994; Eprint. - Simon Peyton Jones,
"Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell".
in Engineering theories of software construction, IOS Press, 2001; Eprint and pdf.- Discusses the IO monad using a "two tier" semantics, with process semantics for the IO part and some denotational semantics for a lazy lambda calculus.