Как быстро распечатать древовидную структуру в строке в Ocaml?

Предположим, у меня есть математическое выражение в виде «дерева» в OCaml. Он представлен в виде алгебраического типа следующим образом:

type expr = 
   Number of int
  |Plus of expr*expr

Ну, это очень упрощенное определение, но его достаточно, чтобы описать проблему.

Я хочу преобразовать его в строку в обратной полировке. обозначение, так что Plus (Number i, Number j) становится (+ ij) . Простая реализация была бы

let rec convert = function
   Number i -> string_of_int i
  |Plus (a,b) -> (let s = convert a in let p = convert b in "(+"^s^" "^p^")")

Но дело в том, что это ' s невероятно медленный на некоторых входных данных (которые имеют большую глубину дерева). Например, на моей машине этот ввод работает 5 секунд:

let rec make_pain so_far = function
  0 -> so_far |i -> make_pain (Plus (Number 1,so_far)) (i-1)

let pain = make_pain (Number 1) 20000

let converted = convert pain

Похоже, что конкатенация строк x ^ y , где y - длинная строка, является проблемой производительности. Действительно, если я заменю выражение "(+" ^ s ^ "" ^ p ^ ")" простым s ^ p , оно станет намного быстрее .

Использование printf вместо конкатенации не ускоряет работу. Преобразование в C может помочь, но нет решения OCaml?

6
задан P Shved 30 January 2011 в 22:12
поделиться