Нет. Начиная с OCaml 4.06, компилятор не делает информацию о типе доступной во время выполнения. Поэтому невозможно иметь автономные программы, которые красиво печатают любые данные OCaml без каких-либо компромиссов. Два основных направления:
- Некоторая форма предварительной обработки, которая выводит принтеры из определений типов. На сегодняшний день лучшим подходом может быть show plugin для получения ppx . Это требует аннотирования каждого определения типа.
- Опираясь только на представление значений во время выполнения. Это не требует усилий со стороны программиста и работает «из коробки» с данными, полученными из внешних библиотек. Однако он не показывает такие вещи, как имена полей записей или любую другую информацию, которая была потеряна во время компиляции. Пример такого подхода подробно описан ниже.
Функция Dum.to_stdout
из пакета dum примет любое значение OCaml, включая циклическое, и напечатает их физическое представление в удобочитаемой форме с учетом данных, доступных только во время выполнения.
Простые вещи дают более или менее то, что можно было бы ожидать:
# Dum.to_stdout ("Hello", 42, Some `Thing, [1;2;3]);;
("Hello" 42 (582416334) [ 1 2 3 ])
Циклический & ndash; и общие значения & ndash; показаны с использованием меток и ссылок. Это круговой список:
# let rec cyc = 1 :: 2 :: cyc;;
# Dum.to_stdout cyc;;
#0: (1 (2 #0))
Мы также можем посмотреть во время выполнения представление функций, модулей и других вещей. Например, модуль Filename
можно проверить следующим образом:
# module type Filename = module type of Filename;;
# Dum.to_stdout (module Filename : Filename);;
(
#0: "."
".."
#1: "/"
#2: closure (#1 #3: closure ())
#4: closure ()
closure (#4)
closure ()
closure ()
closure (#5: closure (#3))
closure (#5)
closure (#5)
closure (closure () #3 #0)
closure (closure () #3 #0)
closure (#6: closure (#2 <lazy>) #7: (#8))
closure (#6 #7)
closure (#7)
closure (#7)
#8: "/tmp"
closure (closure () "'\\''")
)