Redefine the type format of module CamlinternalFormatBasics?

How do you redefine the type format from CamlinternalFormatBasics module?
I tried to redefine the type as I redefine, say, the value map of the module List (include, with type, w/o a new module, etc.).

This is for using a specific format type with sprintf.
Here are the types involved from ('a, unit, string) format to ('a, 'b, 'c, 'd, 'e, 'f) fmt :

Module Printf

val sprintf : ('a, unit, string) format -> 'a

Module Stdlib

type ('a, 'b, 'c) format = ('a, 'b, 'c, 'c) format4 
type ('a, 'b, 'c, 'd) format4 = ('a, 'b, 'c, 'c, 'c, 'd) format6
type ('a, 'b, 'c, 'd, 'e, 'f) format6 = 
  ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.format6

Module CamlinternalFormatBasics

type ('a, 'b, 'c, 'd, 'e, 'f) format6 = 
| 	Format of ('a, 'b, 'c, 'd, 'e, 'f) fmt * string

type ('a, 'b, 'c, 'd, 'e, 'f) fmt = 
| 	Char : ('a0, 'b0, 'c0, 'd0, 'e0, 'f0) fmt ->
          (char -> 'a0, 'b0, 'c0, 'd0, 'e0, 'f0) fmt
| ...

It is not clear to me what you are trying to do. Would you mind sharing an example?

One goal could be to get a typed version of sprintf : ‘a format -> ‘a by encoding it with the following GADT:

type _ format =
  | Lit           : string * 'a format -> 'a format
  | Param_int     : 'a format -> (int -> 'a) format
  | Param_string  : 'a format -> (string -> 'a) format
  | End           : string format

(* Some valid values of that type *)
Lit("foo", End)                   (* : string format *)
Lit("var = ", Param_int End)      (* : int -> string) format *)
Lit("var = ", Param_string End)   (* : (string -> string) format *)
Param_string (Param_int End)      (* : (string -> int -> string) format *)
End                               (* : string format *)

(* Some failing evaluations *)
# sprintf (Lit("foo", End));;
Error: This variant expression is expected to have type
         ('a, unit, string) Stdlib.format
       The constructor Lit does not belong to type CamlinternalFormatBasics.format6
           
# sprintf (Lit("var1", Param_int End)) 1;;
Error: This variant expression is expected to have type
         ('a -> 'b, unit, string) Stdlib.format
       The constructor Lit does not belong to type CamlinternalFormatBasics.format6

# sprintf (Param_string (Param_int End)) "bar" 1;;
Error: This variant expression is expected to have type
         ('a -> 'b -> 'c, unit, string) Stdlib.format
       The constructor Param_string does not belong to type CamlinternalFormatBasics.format6

The error messages suggest that this format type definition should be “inserted” in a qualified manner in lieu of the corresponding Caml’s primitive.
The question may be : how can I do this correctly?

Reference: @xavierleroy 's example in cours n° 3 p. 49 https://www.college-de-france.fr/media/xavier-leroy/UPL6365554635599756529_2.pdf

Ocaml’s format string are already a GADT themselves and are perfectly well typed:
Typically, this format string

let x: _ format = "A string, and a parameter %d";;

is short-hand for

  Format
   CamlinternalFormatBasics.(String_literal ("A string, and a parameter ",
     Int (Int_d, No_padding, No_precision, End_of_format)),
   "A string, and a parameter %d")

There is a bit of magic to make the format strings share the same surface syntax as ordinary strings,
but that is all.

Similarly, the OCaml printing function only work with OCaml’s format strings. You cannot really define your own type and expect sprintf to work with it. The definition of OCaml’s format string type (fmt) is done in CamlinternalBasicsFormats.fmt, and you can re-export it in the same way that you will do with any other type

type ('a,'b,'c,'d,'e,'f) refmt
= ('a,'b,'c,'d,'e,'f) CamlinternalFormatBasics.fmt 
= 
|   Char : 
  ( 'a, 'b, 'c, 'd, 'e, 'f) refmt -> (char -> 'a, 'b, 'c, 'd, 'e, 'f) refmt
| ...

(the definition is very long I am not copying it verbatim here )

But if you want to explore your own format string implementation, it might be easier to define your own type and then define your sprintf function.

Thanks for your precision about the correct way to redefine a type.

I’m doing do that to better understand Caml’s fondations. And also to see how I can specialize the existing stdlib as simply as possible, instead of reinventing the wheel, which is a little bit the case if I redefine my own type fmt or refmt and my own sprintf value.

Should I really understand that it’s by far easier to completely redefine my type own type fmt and value sprintf than try to hook my definition into the existing Stdlib-CamlinternalFormatBasics definition?
Thanks.

BTW, after having completed the expression of refmt , I had some problems while evaluating the example code copied from your example in a Toplevel. I had to fix the following small typo: CamlinternalFormatBasics (instead of CamlInternalFormatBasics).
Maybe you can fix it in your post, in case someone try to do the same as I did?

There is no way to “hook [your] definition into the existing Stdlib-CamlinternalFormatBasics definition”.

If you define your own type of formats, you should also define your own sprinf function over these formats. It’s a good GADT programming exercise, actually.

Thank you for your clear anwer.
I will do it.

One thing that is possible is to define your own generic print function (like printf), reusing the same “format” type, by using CamlinternalFormat.make_printf.

Cheers!
Nicolás