> How do you copy a record without a) updating anything in the record,
> and b) not knowing the type of the record?
>
> type foo = { mutable bar : int }
>
> let a = { bar = 12 }
>
> let copy_record = ???
>
> (* hopefully copy_record is 'a -> 'a, not foo -> foo *)
>
> let b = copy_record a
>
> b.bar <- 234 (* should not modify a.bar *)
The problem is that if the type were 'a -> 'a, it would not apply only
on records, but on just anything. Constrast this with Obj.copy, which
applies on any object, but only on objects.
I believe the natural way to write the copy of a record is
{x with bar = x.bar}. You need to have at least one field, in order to
know the actual type of the record, which gives you the list of fields
to copy.
Another way would be to use the Obj module, which is implementation
dependent. The block must be marked either by a constructor tag or
double_array_tag, otherwise you can break everything. In particulars
objects have an oid, and should not be copied this way.
let copy_record (r : 'a) : 'a =
let obj = Obj.repr r in
if Obj.is_int obj || Obj.size obj = 0 then r else
let tag = Obj.tag obj in
if tag < Obj.object_tag || tag = Obj.double_array_tag then
Obj.obj (Obj.dup obj)
else invalid_arg "copy_record"
Cheers,
Jacques Garrigue
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr