Это похоже на домашнюю работу, поэтому я добавлю несколько пунктов обучения, прежде чем «передать» решение. Давайте посмотрим на код, который вы уже написали, что не является ужасным началом. Я вставил его ниже для справки.
let rec mirror t = function
| Node(Empty, t, Empty) -> t
| Node (t1, t, t2) ->
| _ -> failwith "Empty"
Вы начинаете с того, что позволяете своей функции вызывать себя рекурсивно, добавляя ключевое слово rec
. Вы правы в этом, и на самом деле очень важно осознать, что для решения этой задачи необходимо создать рекурсивную функцию. Потому что, действительно, что значит «отражать» дерево? Зеркальное отображение означает, что в каждом узле, переверните порядок поддеревьев и отразите каждое поддерево.
Это рекурсивное определение, поскольку для зеркального отражения узла вам необходимо отразить поддеревья. Итак, вы правы в добавлении ключевого слова rec
. Однако в вашем коде вы неправильно обрабатываете состояние терминала Empty
. Используя ваше определение btree
, вы в конечном итоге увидите дерево Empty
, что означает, что вы в конечном итоге сгенерируете исключение (используя failwith
). Это явно не желаемое поведение. Как выглядит зеркало пустого дерева? Пустое! Способ обработки этого случая - заменить | _ -> failwith "Empty"
на | Empty -> Empty
.
Теперь в F # let foo = function | ...
является просто синтаксическим сахаром для let foo <arg> = match <arg> with | ...
, что означает, что ваша функция на самом деле принимает два параметра: t
и один, который скрыт сахаром function
. Я предполагаю, что это не то, что вам нужно, поэтому вы должны либо удалить неиспользуемый в данный момент параметр t
, либо заменить function
на match t with
.
Причина, по которой параметр t
в настоящее время не используется, заключается в том, что t
возвращается в целочисленное значение узла в случаях совпадения | Node(..., t, ...)
. Это также означает, что на данный момент лучшим предположением для компиляторов является то, что тип возвращаемого значения mirror
должен быть int
, а не btree
, поскольку в первом случае вы возвращаете int
.
И последнее замечание: нет никакой причины напрямую обращаться с делом с пустыми поддеревьями, поскольку это также просто btree
с.
Имея в виду все вышесказанное, я надеюсь, что имеет смысл, почему мое решение проблемы
let rec mirror = function
| Empty -> Empty
| Node(t1, i, t2) -> Node(mirror t2, i, mirror t1)