que tienen una estructura recursiva inmutable de datos en ocaml que se puede simplificar a algo como esto:Ampliación de tipos inmutables (o: caché rápida de tipos inmutables) en 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)
Es una AST, y a veces se pone bastante complejo (es muy profundo).
hay una función recursiva que evalúa una expresión. Por ejemplo, digamos que,
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
Supongamos ahora que estoy mapeo de una expresión a otra expresión, y tengo que comprobar constantemente el resultado de una expr, a veces más de una vez por el mismo expr, y, a veces por expresiones que recientemente fueron asignadas utilizando el patrón
{ someExpr with eexpr = TSum(someExpr, otherExpr) }
Ahora, la función de resultado es muy ligero, pero el funcionamiento es muchas veces para un AST profunda no será muy optimizado. Sé que podría almacenar en caché el valor usando un Hashtbl, pero AFAIK el Hashtbl solo hará igualdad estructural, por lo que tendrá que recorrer mi AST largo de todos modos. Sé que la mejor opción sería incluir un campo de "resultados" probablemente inmutables en el tipo expr. Pero no puedo.
Entonces, ¿hay alguna forma en Ocaml de almacenar en caché un valor de tipo inmutable, por lo que no tengo que calcularlo ansiosamente cada vez que lo necesito?
Gracias!
¡Gracias, Jeffrey por la excelente respuesta! Así que lo más probable es que pueda hacer el mismo comportamiento con una lista y una función que buscará la lista con == entonces? Leí en el manual de ocaml que la igualdad física tiene un comportamiento indefinido para las estructuras inmutables, aunque se garantiza que cuando A == B, entonces A = B (por supuesto). Cuando uso el patrón {expr con eexpr = TAdd (expr, otherExpr)}, ¿se garantiza que en TAdd (thisExpr, _) thisExpr == expr? – Waneck
Una tabla hash funcionará mejor que una lista, ya que clasificará en contenedores por la igualdad estructural aproximada (es decir, la función hash habitual). A menos que todos sus valores sean estructuralmente iguales, esto será mejor que usar solo una lista. (Puede adaptar su función de hash para ver las partes que difieren más a menudo.) Como dije, creo que la semántica de (==) para valores inmutables está bien para sus propósitos. No hay garantías sólidas de qué es (==) a qué, se permite que el tiempo de ejecución sea arbitrariamente inteligente con valores puros (una razón por la que FP es tan genial). Pero yo diría que sí, en la práctica. –
¡Oh, ya veo! Pero luego tendría que atravesar el gran AST cada vez que se compara con la hash, ¿no? mi función de "resultado" es bastante liviana, por lo que tal vez resulte ser más lenta que llamarla ansiosamente, ¿no es así? – Waneck