(** Solution de Victor Lanvin à l'exercice bonus du TP1. *)

module type P = sig
  type ('a, 'b) fmt
  val printf : ('a, unit) fmt -> 'a
  val i : (int -> 'a, 'a) fmt
  val s : (string -> 'a, 'a) fmt
  val lit : string -> ('a, 'a) fmt
  val concat : ('a, 'c) fmt -> ('c, 'b) fmt -> ('a, 'b) fmt
end

module Myprint : P = struct
  type ('a ,'b) fmt = (string -> 'b) -> string -> 'a
  let printf fmt = fmt print_string ""
  let i cont str x = cont (str ^ (string_of_int x))
  let s cont str x = cont (str ^ x)
  let lit str cont str2 = cont (str2 ^ str)
  let concat fmt1 fmt2 = fun cont -> fmt1 (fmt2 cont)
end

module Test = struct
  open Myprint
  let () =
    let t =
      concat
        (concat
           (concat i (lit ". Test numéro 1"))
           s)
        (concat
           (concat i s)
           (lit "\n"))
    in
      printf t 1 "\n" 2 ". Test numéro 2"
end