package ppx_poly_record
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=30500c00f7ed7eda3d025f54e2de0e796208246637abb516bec4321bb9b0f45a
md5=3dff075d8caf67d771efa6afa8391a26
README.md.html
Polymorphic record in OCaml
This ppx adds polymorphic record.
Poylmorphic records
Polymorphic records provided by Poly_record
has type fields Poly_record.t
, where fields
encodes field type information as object type. For example, < x : int; y : float > Poly_record.t
is a type of polymorphic records whose fields are x : int
and y : float
.
Polymorphic records are like objects but not objects:
Internally, poly records are implemented as hash tables, whose keys are hash of field names. This is just like OCaml's object implementation therefore the operation consts of the both are almost the same.
Type safety by object type. The same restrictions of objects apply to poly records too. For example, you cannot newly add fields by
!{ e with l = e'}
: the expression forcese
contain the fieldl
.Poly records do not contain closures themselves, therefore safely streamable to other programs if fields do not contain closured. Objects have closures by themselves therefore marshaling to other programs is not safe.
Creation of polymorphic records !{ l = e; ...}
Prefixed by !
, the record literal is cahnged from
the normal (monomorphic) records to polymorphic records whose type is _ Ppx_poly_record.Poly_record.t
.
# !{ x = 1; y = 1.0 };;
- : < x : int; y : float > Ppx_poly_record.Poly_record.t = <abstr>
Unlike the normal monomorphic records, it is not required to declare fields of the polymorphic records. They are inferred using OCaml's object type.
Field access r#!l
Accessing fields of the polymorphic records is by r#!x
:
# fun r -> r#!x;;
- : < x : 'tvar_1; .. > Ppx_poly_record.Poly_record.t -> 'tvar_1 = <fun>
Field mutation r#!l := e
Since the polymorphic record has no type declaration, there is no way for it to pre-declare some fields are mutable. Therefore, all the fields of polymorphic records are immutable. Still, if you want mutbility, you can use reference:
# let r = !{ x = ref 0 } in r#!x := 1; r
- : < x : int ref; .. > Ppx_poly_record.Poly_record.t = <abstr>
Record copy with field updates: !{ r with l = e; .. }
The syntax of record copy { r with x = e }
works for polymorphic records too, with the prefix !
:
# fun r -> !{ r with x = 1 };;
- : (< x : int; .. > as 'a) Ppx_poly_record.Poly_record.t
-> 'a Ppx_poly_record.Poly_record.t
Conversion of mono-record syntax uses to poly-record ones automatically: [%poly_record ..]
Inside [%poly_record ..]
, all the monomorphic record syntax constructions are automatically translated to those for polymorphic records. For example, [%poly_record { x = 1; y = 1.0}.x]
is equivalent with !{ x = 1; y = 1.0}#!x
:
{ l = e; ...}
becomes!{ l = e; ...}
{ e with l = e'; ...}
becomes!{ e with l = e'; ...}
r.x
becomesr#!x
r.x <- e
becomesr#!x := e
Inside [%poly_record ..]
, you can use [%mono_record ..]
to locally disable this conversion.
Todo
Printing
Patterns:
!{ x = p }
. This is diffcult...