Basic Monads
Overview
Singatures for state and exception monads, and an input stream monad, with an implementation of an input stream monad with exception handling.
Monads for conversion to arrows.
The basic monad does nothing behind the scenes, no side effects or exceptions.
A state monad represents computations with possible side effects involving reading and/or writing to a state.
An exception monad provides for raising and handling exceptions.
An "InStream" monad is one which reads an input stream as a side effect.
Introduction
Monads for conversion to arrows.
Monads versus Arrows
The XlTools combinator library experiments with the use of arrows to achieve high levels of genericity. Arrows are used because it appears that some of the intended applications will make use of methods which will work with arrows but not with monads. However, many of the applications could be done using monads, and the intention is therefore to implement these as arrows which have been derived from monads via the Kleisli construction, since the monads in these cases are easier to implement than the arrow would be.
Monad Transformers
It is possible that functors could be used as monad transformers in building the monads in this document. Since this is peripheral to my primary concerns at present, I have not done this, and only one Monad implementation is provided. At best the benefits of monad transformers as SML functors would more limited than those of the examples in the literature, which typically make use of the more flexible features available in Haskell. For example, a functor could be written to transform a state monad to a state monad with exceptions, but not for adding exceptions to an arbitrary monad.

(I think the above underestimates what can be done. I need to try some experiments.)

Basic Monad
The basic monad does nothing behind the scenes, no side effects or exceptions.
Signature
A Monad is a type of computations together with two primitive operations. A computation of some type a is a way of (possibly) obtaining a value of type a which may involve complications, such as side effects or failure. The first primitive operation, "unit", takes some value and returns the trivial computation which just returns that value unchanged.

The second, "bind", takes a computation of some type a and function which takes a value of type a and yields a computation of type b and yields a computation of type b. It is intended to provide composition of computations where the second computation takes an input which is the type of value delivered by the first.
xl-sig
signature Monad =
sig
type 'a M
val unit : 'a -> 'a M
val bind : 'a M -> ('a -> 'b M) -> 'b M
end

State Monad
A state monad represents computations with possible side effects involving reading and/or writing to a state.
Signature

xl-sig
signature StateMonad =
sig
include Monad
type state
val mod_state : (state -> 'a * state) -> 'a M
end

Exception Monad
An exception monad provides for raising and handling exceptions.
Using SML exceptions
I have attempted to use SML exceptions for implementing this feature, since this ought to be more efficient than the usual way of doing this in pure functional languages. Our interest in using monads and arrows is because of the genericity obtained by having a combinator library which can be re-targetted by changing an underlying monad or arrow. The purpose is not to find a pure way of providing imperative features.
Signature

xl-sig
signature XMonad =
sig
include Monad
type failinfo = string
type abortinfo = string
exception Fail of failinfo
exception Abort of abortinfo
val fail : failinfo -> 'a M
val abort : abortinfo -> 'a M
val catchfail : 'a M * (failinfo -> 'a M) -> 'a M
val catchabort : 'a M * (abortinfo -> 'a M) -> 'a M
end

State Monad with Exceptions

xl-sig
signature StateXMonad =
sig
include XMonad
type state
val mod_state : (state -> 'a * state) -> 'a M
end

InStream Monad
An "InStream" monad is one which reads an input stream as a side effect.
inStream Monad functor
This functor creates a monad for processing an input stream (which is the "state" of the monad).
xl-sml
functor InStreamMonad (XlStream:XlStream):StateXMonad =
struct
open XlStream
type state = inStream

type 'a M = state -> 'a * state

fun unit x f = (x,f)

fun bind am fabm s =
let val (a,s) = am s
in fabm a s
end

fun mod_state f = f

type failinfo = string
type abortinfo = string
exception Fail of failinfo
exception Abort of abortinfo

fun fail failinfo = raise Fail failinfo
fun abort abortinfo = raise Abort abortinfo
fun catchfail (am,fam) s = am s handle Fail info => fam info s
fun catchabort (am,aam) s = am s handle Abort info => aam info s
end;


up quick index © RBJ

$Id: BasicMonads.xml,v 1.1.1.1 2000/12/04 17:24:50 rbjones Exp $