pbp
pbp

Reputation: 1481

Records with similar fields in OCaml

In this answer, the suggested way of "attaching" meta information to types was using a record:

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

but what if I have multiple types I'd like to wrap with meta information? Apparently all field names in record types must have different names, and writing:

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

seems redundant :/. Classes are the only way to solve this? I'd like to avoid dealing with classes, if possible.

Upvotes: 3

Views: 282

Answers (2)

gasche
gasche

Reputation: 31459

Jeffrey's solution is correct and scales perfectly to recursive types.

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

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

It is still possible to use the previous two-time definition of your type, as follows:

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

Finally, a slightly different style is to use "open recursion", that is to define only an "derecursified type" open_exp with free parameters instead of recursive occurences. You can then get the recursive type back by taking the fixpoint; you can take different fixpoint, one with no additional information, and one with location interleaved for example. This is a generic construction to insert information at recursion sites, and its term-level counterpart allows for weaving different things in a recursive function (memoization, profiling, debug, etc.).

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

Upvotes: 3

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66803

You can use parameterized type, perhaps.

type 'a wrapped = { base: 'a; extra: meta }

Upvotes: 5

Related Questions