[MLton] printf with no infixes
Stephen Weeks
MLton@mlton.org
Wed, 24 Aug 2005 21:35:03 -0700
The latest varargs hack that I sent yesterday can be used to improve
printf so that no infix operators are needed. The code is below. I
think there is still room for a couple of improvements, namely: avoid
the intermediate list construction (presumably using continuations)
and allow the expression of other varargs functions with non-unit
result types, e.g. format.
----------------------------------------------------------------------
signature PRINTF =
sig
type ('a, 'b, 'c) v
type ('a, 'b, 'c) u = string -> ('a, 'b, 'c) v -> 'c
type ('x, 'a, 'b, 'c) f = ('x -> 'a, 'b, ('a, 'b, 'c) u) v
val $ : (unit, 'b, 'b) v
val D: (int, 'a, 'b, 'c) f
val G: (real, 'a, 'b, 'c) f
val S: (string, 'a, 'b, 'c) f
val newFormat: ('x -> string) -> ('x, 'a, 'b, 'c) f
val printf: ('a, 'a, 'b) u
end
functor F (S: PRINTF) =
struct
open S
val () = printf "Hello.\n"$
val () = printf "An int "D" and an int "D".\n"$ 13 14
val () = printf "An int "D" and a real "G".\n"$ 13 3.1415
val () = printf "A real "G" and a real "G".\n"$ 13.1 3.1415
end
structure Printf: PRINTF =
struct
type 'a k = string list -> 'a
type ('a, 'b, 'c) v = string * ('a k -> 'b k) -> 'c
type ('a, 'b, 'c) u = string -> ('a, 'b, 'c) v -> 'c
type ('x, 'a, 'b, 'c) f = ('x -> 'a, 'b, ('a, 'b, 'c) u) v
fun printf s f = f (s, fn k => k)
fun $ (s, m) = m (fn ss => List.app print (rev (s :: ss))) []
fun newFormat toString (s, m) s' f =
f (s', fn k => m (fn ss => fn x => k (toString x :: s :: ss)))
val C = fn z => newFormat Char.toString z
val D = fn z => newFormat Int.toString z
val G = fn z => newFormat Real.toString z
val S = fn z => newFormat (fn s => s) z
end
structure Z = F (Printf)