module type PRINTF = sig
type ('a,'r) fmt
val fmt_i : (int -> 'r, 'r) fmt
val fmt_lit : string -> ('r,'r) fmt
val fmt_concat : ('a,'b) fmt -> ('b,'r) fmt -> ('a,'r) fmt
val print : ('a,unit) fmt -> 'a
end
module T (P:PRINTF) = struct
open P
let (^) = fmt_concat
let () =
print fmt_i 12 ;
print (fmt_lit "\nfoo\n") ;
print (fmt_i ^ fmt_lit "..." ^ fmt_i ^ fmt_lit "\n") 42 24
end
module Printf : PRINTF = struct
type ('a,'r) fmt = (unit -> 'r) -> 'a
let print fmt = fmt (fun x -> x)
let fmt_i k n = print_int n ; k ()
let fmt_lit s k = print_string s ; k ()
let fmt_concat f1 f2 k = f1 (fun () -> f2 k)
end
module TP = T(Printf)
module type SCANF = sig
type ('a,'r) fmt
val fmt_i : (int -> 'r, 'r) fmt
val fmt_lit : string -> ('r,'r) fmt
val fmt_concat : ('a,'b) fmt -> ('b,'r) fmt -> ('a,'r) fmt
val scan : ('a,unit) fmt -> 'a -> unit
end
module Scanf : SCANF = struct
type ('a,'r) fmt = ('r -> unit) -> 'a -> unit
let scan fmt = fmt (fun () -> ())
let fmt_i k f =
let n = read_int () in
k (f n)
let fmt_lit s k f =
for i = 1 to String.length s do
ignore (input_char stdin)
done ;
k f
let fmt_concat f1 f2 k f = f1 (f2 k) f
end
module type FMT = sig
type ('a,'b) fmt
include (PRINTF with type ('a,'b) fmt := ('a,'b) fmt)
include (SCANF with type ('a,'b) fmt := ('a,'b) fmt)
end
module Fmt : FMT = struct
type ('a,'b) fmt = ('a,'b) Printf.fmt * ('a,'b) Scanf.fmt
let scan (_,fmt) = Scanf.scan fmt
let print (fmt,_) = Printf.print fmt
let fmt_i = Printf.fmt_i, Scanf.fmt_i
let fmt_lit s = Printf.fmt_lit s, Scanf.fmt_lit s
let fmt_concat (a,b) (x,y) = Printf.fmt_concat a x, Scanf.fmt_concat b y
end
module S (P:FMT) = struct
open P
let (^) = fmt_concat
let () =
print (fmt_lit "Please input <int>\n+<int>\n:\n") ;
scan (fmt_i ^ fmt_lit "+" ^ fmt_i)
(fun x y ->
print (fmt_i ^ fmt_lit "*" ^ fmt_i ^ fmt_lit "\n") x y)
end
module SF = S(Fmt)