У меня есть рекурсивная неизменяемая структура данных в 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, иногда более одного раза для одного и того же выражения, а иногда длявыражения, которые недавно были сопоставлены с использованием шаблона
{ someExpr with eexpr = TSum(someExpr, otherExpr) }
Теперь функция результата очень легкая, но многократный запуск ее для глубокого AST не будет очень оптимизирован.Я знаю, что могу кэшировать значение, используя Hashtbl, но AFAIK Hashtbl будет выполнять только структурное равенство, поэтому ему все равно придется пересекать мой длинный AST.Я знаю, что лучшим вариантом будет включение, вероятно, неизменяемого поля «результат» в тип expr.Но я не могу.
Так есть ли в Ocaml способ кэшировать значение для неизменяемого типа, поэтому мне не нужно вычислять его с нетерпением каждый раз, когда мне это нужно?
Спасибо!