У меня есть рекурсивная неизменяемая структура данных в 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 способ кэшировать значение в неизменяемый тип, чтобы мне не приходилось с нетерпением вычислять его каждый раз, когда оно мне нужно?
Спасибо!