As a newbie in functional programming (OCaml), I stuck with that problem.
I came up with a code shown below:
let rec height tr =
match tr with
| Node(d,[]) -> 1
| Node(d,[t1]) -> 1 + height t1
| Node(d,[t1;t2]) -> 1 + max (height t1) (height t2)
But the top-level (utop) for OCaml gives a warning:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Node (_, _::_::_::_)
And when I run
let t : int gt =
Node('a',
[Node('b',[]);
Node('c',
[Node('d',
[Node('e',[])]);
Node('f',[]);
Node('g',[])])
]);;
height t;;
utop throws exception about match failure.
I also implemented this:
let rec height' tr =
match tr with
| Node(d,[]) -> 1
| Node(d,_::xs) -> 1 + max (List.map height' xs)
and it returns with
Line31 | | Node(d,_::xs) -> 1 + max (List.map height' xs)
^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type int list -> int list
but an expression was expected of type int
In addition, I also tried another way:
let rec height tr =
match tr with
| Node(d,[]) -> 1
| Node(d,[t1]) -> 1 + height t1
| Node(d, t1::t2) ->
if t2=[]
then 2
else
2 + height t2
then the error was:
Line26 | 2 + height t2
^^
Error: This expression has type 'a gt list
but an expression was expected of type 'a gt
So, how can I overcome this problem?
Your problem
Your
heightfunction expects a value of type'a gt. When you callheight t2,t2is the tail of a list, which is aa gt list. If you pass this toheightyou get a type mismatch.How to approach this problem
Given a tree definition:
Writing a
heightfunction is straightforward, and I think you may be overthinking it given the number of cases in your pattern matching.With any recursion the key is a base case. You have that:
A node with an empty list has a height of 1. The actual data in the tree is unimportant, so we use
_in the pattern match.The only other possibility is that the list is not empty. So we can pattern match a non-empty list. Again, the first node doesn't matter.
Now we have to turn a
'a gt listinto an int.heightwill turn a'a gtvalue into an int for me. So why don't I just mapxs?Ah, but that turns
xsinto anint list, which we can't add to anint. We can sum that list usingfold_left.One more thing
Using the
functionkeyword, we can simplify this.