Форматирование вывода OCaml toplevel

Если я выполнил следующее в OCaml toplevel:

#require "num";;
open Ratio;;

ratio_of_int 2;;

Вывод:

- : Ratio.ratio = <ratio 2/1>

Как такое форматирование возможно? Источники сообщают мне, что Ratio.ratio - это запись. Таким образом, результат должен быть более сродни

{numerator = <big_int 2>; denominator = <big_int 1>; normalized = true}

Я пробовал посмотреть, как отношение выходного сигнала как-то жестко запрограммировано в верхнем уровне, но этот поиск оказался бесплодным. Будучи новичком в OCaml, я должен спросить, не хватает ли я чего-то важного? На языке, который перегрузил строковые функции, это было бы не странно, но в случае OCaml я считаю это поведение совершенно неуместным.

Ответ 1

В Findlib есть довольно принтер специально для модуля отношения. Вместо того, чтобы печатать <abstr> (интерфейс не раскрывает запись), он печатает то, что вы видели. Если вы хотите проверить это, посмотрите на findlib/num_top_printers.ml:

let ratio_printer fmt v =
  Format.fprintf fmt "<ratio %s>" (Ratio.string_of_ratio v)

Ответ 2

Toplevel имеет директиву #install_printer, которая принимает функцию для печати любого типа.

Например, вы можете переопределить, как печатать целые числа следующим образом:

let print_integer ppf n = Format.fprintf ppf "Integer(%d)" n
#install_printer print_integer

#install_printer выбирает принтеры в зависимости от типа функции, заданной как аргумент (здесь Format.formatter -> int -> unit).