Reputation: 39
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
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
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
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