Formatter string provided by a function. How can I do that?

Hi there!
I’m stuck again.

Let’s say I want to print some text, formatted by a formatting string. Simple!

      bprintf buff "%s<%s/>" (String.make (indent * level) ' ') element.tagStr;

Now, the formatter string gets “more complex” and is provided by the function getFmt

type tagVariant = XvTagEmpty | XvTagOpen | XvTagClose | XvNoTag (* <x/> | <x> | </x> | no tag found *)

let rec xmlFormat ?(indent = 2) ?(level = 0) element =
  let getFmt tagType =
    match tagType with 
    | XvTagEmpty -> "%s<%s/>" 
    | XvTagOpen  -> "%s<%s>"
    | XvTagClose -> "%s<%s/>"
    | XvNoTag    -> "%s error %s"
  in

  let buff = Buffer.create 100 in
      bprintf buff (getFmt XvTagEmpty) (String.make (indent * level) ' ') element.tagStr;

The formatter string always has the same pattern of requiring two strings, as in the initial example.
I’m sorry, but I don’t understand how to get that working. It seems that Scanf.format_from_string is part of the solution. I do understand why OCaml is so strict about this subject. It needs to analyze the formatter string to avoid any type mismatches.

Any help/hints are welcome.

The compiler has no way of knowing that the return type of getFmt is a formatting string instead of a plain string (since both use the same syntax). You need to help the compiler by annotating the function:

let getFmt tagType : _ format =

Cheers,
Nicolas

4 Likes