[MLton] handling a variable number of arguments in SML
Stephen Weeks
MLton@mlton.org
Tue, 23 Aug 2005 15:48:12 -0700
> the simplest version I could come up with, which shows how to define
> a function "f" that takes a variable number of "a" arguments, and
> when it receives the end of arguments marker, "$", returns the
> number of "a"s it received.
The approach can be generalized to allow one to define a fold
function that takes a variable number of arguments.
----------------------------------------------------------------------
signature S =
sig
type ('a, 'b, 'k) v
type ('a, 'b, 'k) u = ('a, 'b, 'k) v -> 'k
val $ : ('a, 'b, 'b) v
val fold: 'b * ('a * 'b -> 'b) -> ('a, 'b, 'k) u
val a: 'a -> ('a, 'b, ('a, 'b, 'k) u) v
end
functor F (S: S) =
struct
open S
fun p i = print (concat [Int.toString i, "\n"])
val () = p (fold (0, op +) (a 1) (a 2) (a 3) $)
end
structure S: S =
struct
type ('a, 'b, 'k) v = 'b * ('a * 'b -> 'b) -> 'k
type ('a, 'b, 'k) u = ('a, 'b, 'k) v -> 'k
fun $ (b, _) = b
fun fold z v = v z
fun a x (b, f) v = v (f (x, b), f)
end
structure Z = F (S)
----------------------------------------------------------------------
This has one advantage over the usual List.fold because MLton will
simplify away all the continuation stuff and will thus be encourage to
compute the fold at compile time. For example, in the above, I would
bet that the sum, 6, is computed at compile time.
I'm unsure of what advantage, if any, the continuation approach has
over the composition-of-arguments approach.
----------------------------------------------------------------------
infix 4 &
signature S =
sig
type ('a, 'b) arg
val & : ('a, 'b) arg * ('a, 'b) arg -> ('a, 'b) arg
val fold: 'b * ('a * 'b -> 'b) -> ('a, 'b) arg -> 'b
val a: 'a -> ('a, 'b) arg
end
functor F (S: S) =
struct
open S
fun p i = print (concat [Int.toString i, "\n"])
val () = p (fold (0, op +) (a 1 & a 2 & a 3))
end
structure S: S =
struct
type ('a, 'b) z = 'b * ('a * 'b -> 'b)
type ('a, 'b) arg = ('a, 'b) z -> ('a, 'b) z
val op & = op o
fun fold z (v: ('a, 'b) arg) = #1 (v z)
fun a x (b, f) = (f (x, b), f)
end
structure Z = F (S)
----------------------------------------------------------------------