[MLton] Monadic MLton.Vector.create with update
Vesa Karvonen
vesa.karvonen@cs.helsinki.fi
Wed, 29 Mar 2006 10:08:37 +0300
The earlier monadic vector create interface didn't allow updates during the
construction of the vector. Below is an improved interface and a similar
inefficient mock implementation, because I can't easily get to the MLton
Primitive stuff when testing my snippets of code on the SML/NJ top-level...
I tested that update works, but I don't have any example actually using update.
Maybe Stephen and/or Henry has an example in mind?
It is impossible to circumvent the interface (except through callcc and other
similar operators) and make updates to the vector after it has been constructed.
This is simply because only the create function can execute the constructed
monad and each time you call create a fresh vector is allocated.
I think that a monadic interface has some pleasing properties compared to an
interface that simply passes sub and update to the function. For instance,
there is no need to poison the sub and update functions after the vector has
been created.
-Vesa Karvonen
infix >>=
fun K x _ = x
fun fail msg _ = raise Fail msg
signature CREATE =
sig
type ('a, 'e) m
val create : int * (int -> ('e, 'e) m) -> 'e vector
val return : 'e -> ('e, 'e) m
val >>= : ('a, 'e) m * ('a -> ('b, 'e) m) -> ('b, 'e) m
val sub : int -> ('e, 'e) m
val update : int * 'e -> (unit, 'e) m
end
structure Create :> CREATE =
struct
structure A = Array
type ('a, 'e) m = int * 'e A.array -> 'a
fun create (n, f) =
let
val a = A.tabulate (n, K (f 0 (0, A.tabulate (0, fail "BUG"))))
in
A.modifyi (fn (i, _) => f i (i, a)) a
; Vector.tabulate (n, fn i => A.sub (a, i))
end
fun return x _ = x
fun (mA >>= a2mB) mv = a2mB (mA mv) mv
fun sub i (m, v) = if i<m then A.sub (v, i) else raise Subscript
fun update (i, e) (m, v) = if i<m then A.update (v, i, e) else raise Subscript
end
local
open Create
in
fun fib n =
create (n,
fn i =>
if i <= 1 then
return (IntInf.fromInt i)
else
sub (i-1) >>= (fn x =>
sub (i-2) >>= (fn y =>
return (x+y))))
end