beezz
beezz

Reputation: 2428

using record field in other field of the same record

I wonder if it is possible in OCaml to use one field of record in the other field in the same record.

Basicaly, I have field with function in which I would like to use also other, values, fields of the same record so when the value change the function will use the new value.

I can do it with setting the function field mutable and update it after the record is created e.g.

type 'a cell =
  { mutable value: 'a
  ; mutable fn: unit -> 'a }

let create_cell ~(value : 'a) : 'a cell =
  let c = {value; fn= (fun () -> value + 42)} in
  let _ = c.fn <- (fun () -> c.value + 42) in
  c

I was wondering if it is possible without fn field being mutable and in one go.

Upvotes: 3

Views: 274

Answers (1)

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66818

You can use let rec to make the function refer to the record it is part of:

# type 'a cell = { mutable value : 'a ; fn : unit -> 'a };;
type 'a cell = { mutable value : 'a; fn : unit -> 'a; }
# let rec r = { value = 14; fn = fun () -> r.value + 14 };;
val r : int cell = {value = 14; fn = <fun>}
# r.fn ();;
- : int = 28
# r.value <- 10;;
- : unit = ()
# r.fn ();;
- : int = 24

If I understand correctly, this what you'd like to do.

So then your create_cell function might look like this:

let create_cell ~(value : 'a) : 'a cell =
  let rec c = {value; fn= (fun () -> c.value + 42)} in
  c

It seems to work:

# let mycell = create_cell ~value: 88;;
val mycell : int cell = {value = 88; fn = <fun>}
# mycell.fn ();;
- : int = 130
# mycell.value <- 100;;
- : unit = ()
# mycell.fn ();;
- : int = 142

Upvotes: 5

Related Questions