user3460123
user3460123

Reputation: 39

OCaml option type in binary tree

I have a few problems creating a tree size function with type 'a option tree -> int

type 'a tree = Leaf of 'a
         | Fork of 'a * 'a tree * 'a tree

How would I create a t_opt_size function with type 'a option tree -> int?

I know I would have to use Some and the None operate.

I have this so far, but it's complicated to match with the option type.

let rec t_size (tr: 'a tree): int = 
    match tr with
    | Leaf _ -> 1
    | Fork (_, t1, t2) -> t_size t1 + t_size t2 + 1

Upvotes: 1

Views: 709

Answers (3)

Bergi
Bergi

Reputation: 664405

If you don't want to count all values in the tree as 1, but each depending on its contents, write a function that determines the count per value and use that:

let weight = function
    | _ -> 1 (* or anything else *)

let rec t_opt_size (tr: 'a tree): int = match tr with
    | Leaf v -> weight v
    | Fork (v, t1, t2) -> t_size t1 + t_size t2 + weight v

You even might want to generalise and pass the weight function as a parameter to t_size instead of writing different size functions that all use their own weighting.

Upvotes: 0

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66818

I assume from your comments that you want a leaf that looks like (Leaf None) not to be counted in your tree size calculation.

Seems like the key is to split this:

| Leaf _ -> 1

Into two cases:

| Leaf None -> (* Left as exercise *)
| Leaf (Some _) -> (* Left as exercise *)

Since OCaml will take the first match, you can abbreviate this as follows if you like:

| Leaf None -> (* Left as exercise *)
| Leaf _ -> (* Left as exercise *)

You should make a similar change to the Fork case, though I have to say that Fork (None, l, r) doesn't really work for constructing a search tree.

Upvotes: 3

coredump
coredump

Reputation: 38799

If you want to generalize, you might need to write a generic tree walker which accepts a visitor function. I recommend you try to implement fold_tree, which accepts: (1) a fold function, taking some value, a tree and producing a new result ('a -> 'b t -> 'c), (2) an initial element of type 'a as well as (3) a tree. Then, fold_tree returns a value of type 'c. Then, you should be able to call fold_tree with a function that skips over None leaves but otherwise increment the count like you did.

Upvotes: 1

Related Questions