Вы почти у цели. Идея с охраной | (Empty, )
хороша. Если применяется в правильном положении, это работает:
let rec leftmost t =
match t with
Node(Empty, n, _) -> n
| Node (t, _, _) -> leftmost t
| _ -> failwith "Empty"
Важной частью является то, что нам нужно остановиться на текущем узле t
и вернуть его полезную нагрузку n
, как только следующий левый потомок будет Empty
.
Для полноты: я бы рекомендовал назвать левое поддерево иначе, чем текущий корень, и выровнять регистры:
let rec leftmost t =
match t with
| Node(Empty, n, _) -> n
| Node (l, _, _) -> leftmost l
| _ -> failwith "Empty"
Также есть ярлык для let f x = match x with | P
: let f = function | P
, который избавляет от необходимости придумывать имя для параметра:
let rec leftmost = function
| Node(Empty, n, _) -> n
| Node (l, _, _) -> leftmost l
| _ -> failwith "Empty"