0

I am implementing binary search trees in OCaml, trying to use as much imperative programming as possible.

I have the following data type:

type tKey = Key of int;;

type tBST = Null | Pos of node ref
            and node = {mutable key : tKey; mutable left : tBST; mutable right : tBST};;

I am having trouble with this function:

let createNode k tree = 
    tree := Pos ({key = k; left = Null; right = Null});;

Error: This record expression is expected to have type node ref
       The field key does not belong to type ref

A binary search tree can be either Null (means empty tree) or a Pos. A tree Pos is a pointer to a node, and a node is a structure of a key and 2 other trees (left and right).

My main goal here is to have a tree that is modified after functions are over. Passing tree by reference so when createNode is over, the tBST I passed as parameter is modified.

Question: is actually possible to do what I am trying in OCaml? if so, how could I change my function createNode and/or data type to make this happen?

Thank you very much.

deko
  • 463
  • 1
  • 6
  • 17

3 Answers3

1

It is possible, but you need to create the Pos node with a reference explicitly:

Pos (ref {key = k; (*...*)})

Whether what you are trying to do is recommended practice in a language like Ocaml is a different story, though.

Andreas Rossberg
  • 34,518
  • 3
  • 61
  • 72
  • Thank you sooo much. Exactly, I am well aware it would be way easier using recursive and pure code, which I already have implemented. Thanks!! – deko Oct 03 '17 at 15:03
1

The question has already been answered. I would just like to add a side note: The use of ref seems superfluous in this case.

A value of type tBST is either Null or a mutable pointer. If it is Null it will remain Null. If it is non-Null, it will remain non-Null, but the actual pointer might change. That might well be what you intended, but I have my doubts. In particular, what tBST does not do, is to emulate C-style pointers (which are either null or really point somewhere). I suspect, though, that that was your intention.

The idiomatic way to emulate C-style pointers is to just use the built-in option type, like so:

type tBST = node option

A value of type node option is either None or Some n, where n is a pointer to a value of type node. You use tBST for mutable fields (of the record node), so you would effectively have mutable C-style pointers to nodes.

kne
  • 1,398
  • 7
  • 12
  • Mmmm thank you so much for the info kne, never heard about that before. That would make a lot of more sense regarding the Null case. However, I don't only want to emulate C-style pointers but to have a real functionality – deko Oct 05 '17 at 00:47
0

Here is what you probably had in mind:

type tree = node option ref
and node  = {
  mutable left: tree;
  mutable key: int;
  mutable right: tree;
};;

let t0 : tree = ref None;;
let t1 : tree = ref (Some { left = ref None; key = 1; right = ref None; }) ;;

let create_node key tree = 
  tree := Some { left = ref None; key; right = ref None; }

No need to have a separate type for key but you can if you want it, and with the latest OCaml there no runtime overhead for it.

Vasile Rotaru
  • 452
  • 4
  • 11