我在OCaml中有一个递归的不可变数据结构,可以简化为以下内容:
这是一个AST(抽象语法树),有时它会变得相当复杂(非常深)。
有一个递归函数来评估表达式。例如,假设:
现在假设我正在将一个表达式映射到另一个表达式,并且我需要不断检查一个表达式的结果,有时需要多次检查相同的表达式,有时需要检查最近使用模式映射的表达式。
现在,结果函数非常轻量级,但对于深层AST的多次运行并不是很优化。我知道可以使用Hashtbl缓存值,但据我所知,Hashtbl只会进行结构相等性检查,因此它仍然需要遍历我的长AST。我知道最好的选择是在expr类型中包含一个可能是不可变的“result”字段。但我不能这样做。
那么,在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
现在假设我正在将一个表达式映射到另一个表达式,并且我需要不断检查一个表达式的结果,有时需要多次检查相同的表达式,有时需要检查最近使用模式映射的表达式。
{ someExpr with eexpr = TSum(someExpr, otherExpr) }
现在,结果函数非常轻量级,但对于深层AST的多次运行并不是很优化。我知道可以使用Hashtbl缓存值,但据我所知,Hashtbl只会进行结构相等性检查,因此它仍然需要遍历我的长AST。我知道最好的选择是在expr类型中包含一个可能是不可变的“result”字段。但我不能这样做。
那么,在Ocaml中是否有一种方法可以将值缓存到不可变类型中,以便每次需要时不必急切地计算它?
谢谢!