I am implementing a couple of trees in F#: a standard BST, a Red Black Tree, AVL tree, Treaps, etc.
Other than the insert
/ remove
operations, they all seem to share the same set of functions: size
, height
, get
, contains
, floor
, ceil
, toSeq
, blablabla. Let's call them "invariant tree functions".
Although the core of those functions is pretty much the same, they operate over different discriminated unions, that is, different trees are defined by different discriminated unions. Is there a way to easily parameterize my invariant tree functions such that every time I implement a new kind of tree I only have to glue the discriminated union with those invariant implementations?
Here is an example of a BST's discriminated union and its get
function:
(* Searches for a node with the given key in this BST and returns the
result in the form of an option. Executes in O(lg n) time. *)
type t<'K, 'V> =
| Empty
| Node of 'K * 'V * t<'K, 'V> * t<'K, 'V>
let rec get k = function
| Empty -> None
| Node(k', v, l, r) ->
if k < k' then get k l
elif k > k' then get k r
else Some(v)
Thanks