Имеется вот такое бинарное дерево:
type 'a tree =
| Nil
| Node of ('a tree) * 'a * ('a tree)
Требуется (в качестве упражнения) написать для него функцию map, которая применяла бы некоторую другую функцию ко всем элементам в узлах дерева, и возвращала дерево такой же конфигурации, где в узлах стоят результаты. Надо написать в функциональном стиле, используя только хвостовую рекурсию. У меня получилось так:
let map f t =
let rec map' s a =
match s with
| [] -> a
| h :: s' ->
match h with
| Nil -> map' s' (None :: a)
| Node(l, v, r) ->
map' (l :: r :: s') (Some (f v) :: a)
let message = "Unexpected stack state"
let rec decode s a =
match s with
| [] -> a
| None :: t -> decode t (Nil :: a)
| Some(v) :: s' ->
match a with
| l :: r :: a' -> decode s' (Node(l, v, r) :: a')
| _ -> failwith message
match decode (map' [t] []) [] with
| [h] -> h
| _ -> failwith message
Можно ли сократить/улучшить этот алгоритм? Может быть, здесь можно как-то привинтить continuation passing?