Записи с похожими полями в OCaml - PullRequest
3 голосов
/ 22 января 2012

В этом ответе предложенный способ «прикрепления» метаинформации к типам - использование записи:

type _foo = ... 
and foo = {n:_foo; m:meta}

а что если у меня есть несколько типов, которые я хотел бы обернуть метаинформацией? Очевидно, что все имена полей в типах записей должны иметь разные имена и запись:

type _foo = ... 
and foo = {n:_foo; m:meta}
...
type _fooX = ... 
and fooX = {nX:_fooX; mX:meta}

кажется избыточным: /. Занятия - единственный способ решить это? Я хотел бы избежать занятий с классами, если это возможно.

Ответы [ 2 ]

5 голосов
/ 22 января 2012

Вы можете использовать параметризованный тип, возможно.

type 'a wrapped = { base: 'a; extra: meta }
3 голосов
/ 23 января 2012

Решение Джеффри является правильным и идеально масштабируется для рекурсивных типов.

type location
type 'a loc = { a : 'a; loc : location }

type exp = Int of int | Add of exp loc * exp loc

Все еще возможно использовать предыдущее двухкратное определение вашего типа, как показано ниже:

type exp_data = Int of int | Add of exp * exp
and exp = exp_data loc

Наконец, немного другой стиль - использовать «открытую рекурсию», то есть определять только «нерекурсивный тип» open_exp со свободными параметрами вместо рекурсивных вхождений.Затем вы можете получить рекурсивный тип обратно, взяв фиксированную точку;Вы можете использовать другую точку фиксации, одну без дополнительной информации, а другую с чередованием местоположения, например.Это общая конструкция для вставки информации на сайты рекурсии, а ее аналог уровня терминов позволяет создавать разные вещи в рекурсивной функции (запоминание, профилирование, отладка и т. Д.).

type 'e open_exp = Int | Add of 'e * 'e
type simple_exp = Simple of simple_exp open_exp
type located_exp = Loc of located_exp loc open_exp
...