Расширение неизменяемых типов (или: быстрый кеш для неизменяемых типов) в OCaml

У меня есть рекурсивная неизменяемая структура данных в ocaml, которую можно упростить примерно так:

type expr =
{
    eexpr : expr_expr;
    some_other_complex_field : a_complex_type;
}

and expr_expr =
    | TInt of int
    | TSum of (expr * expr)
    | TMul of (expr * expr)

Это AST, и иногда он становится довольно сложным (очень глубоким).

существует рекурсивная функция, оценивающая выражение. Например, скажем,

let rec result expr =
    match expr.eexpr with
        | TInt i -> i
        | TSum (e1, e2) -> result e1 + result e2
        | TMul (e1, e2) -> result e1 * result e2

Теперь предположим, что я отображаю выражение в другое выражение, и мне нужно постоянно проверять результат expr, иногда более одного раза для того же expr, а иногда и для выражений, которые недавно были сопоставлены использование шаблона

{ someExpr with eexpr = TSum(someExpr, otherExpr) }

Теперь функция результата очень легкая, но ее многократное выполнение для глубокого AST не будет очень оптимизировано. Я знаю, что могу кэшировать значение с помощью Hashtbl, но AFAIK, Hashtbl будет выполнять только структурное равенство, поэтому ему все равно нужно будет пройти мой длинный AST. Я знаю, что лучшим вариантом было бы включить, вероятно, неизменяемое поле «result» в тип expr. Но я не могу.

Так есть ли в Ocaml способ кэшировать значение в неизменяемый тип, чтобы мне не приходилось с нетерпением вычислять его каждый раз, когда оно мне нужно?

Спасибо!

5
задан Waneck 3 February 2012 в 01:20
поделиться