Что ж, взглянем на эту функцию. Первое, что бросается в глаза, — это деструктивное, с присваиваниями, построение строки. Вообще, в OCaml это нормально, но в данном случае никакого выигрыша не даёт (для инкрементального построения строк надо использовать Buffer). Поэтому перепишем terms_to_string в чистом виде с использованием стандартной функции fold_left. Вообще, если из списка нам нужно сделать одно значение, это почти всегда указывает на применимость свёртки (fold).
| Код | let terms_to_string = function | [] -> "" | t::ts -> List.fold_left (fun s x -> s ^ ", " ^ term_to_string x) (term_to_string t) ts |
К функции явно напрашивается обобщение: списки, разделённые запятыми, можно много из чего строить. Параметризуем её функцией перевода элемента списка в строку:
| Код | let comma_separated_list tostr = function | [] -> "" | t::ts -> List.fold_left (fun s x -> s ^ ", " ^ tostr x) (tostr t) ts |
Стоит обратить внимание на получившийся тип:
| Код | val comma_separated_list : ('a -> string) -> 'a list -> string |
Если вдруг эта функция станет узким местом, можно переписать с помощью Buffer:
| Код | let comma_separated_list tostr = function | [] -> "" | t::ts -> let b = Buffer.create 10 in Buffer.add_string b (tostr t); List.iter (fun x -> Buffer.add_string b ", "; Buffer.add_string b (tostr x)) ts; Buffer.contents b |
Теперь terms_to_string можно записать очень просто:
| Код | let terms_to_string = comma_separated_list term_to_string (* карринг *) |
Ну и наконец сама функция string_of_atomformula:
| Код | let string_of_atomformula = function | AtomFormula(PredicateName name, terms) -> "AtomFormula(\"" ^ name ^ "\"" ^ terms_to_string terms ^ ")" |
P.S. Темы всё-таки корректнее называть надо. |