我有一个 environment 列表,用于保存变量和值之间的关联,例如env = [("x", 1), ("y", 2), ("z", 3), ...]
。我还有另一个替换列表(由模式匹配控制函数返回),它保持变量和模式之间的关联,例如s = [("v", Var_p "z"), ("w", Var_p "v"), ("u", Var_p "w"), ...]
。让我们考虑第一对("v", Var_p "z")
:我的函数应该检查环境中z
对应的值,在v
和z
的值之间创建一个新的关联(即{ {1}})并将其放入环境中。我的这个函数的代码如下。
("v", 3)
此处,fun augment_env ([], e : env) = e
| augment_env (s :: srest, e : env) =
let
val (a, b) = s
in
case b of
Const_p i => [] @ augment_env_with_vars (srest, e)
| Var_p x =>
if (exists (e, x)) then (a, lookup (e, x)) :: augment_env_with_vars (srest, e)
end;
是替换列表,s
和exists
是检查环境中是否存在变量并分别查找相应值的函数。此函数的问题是仅适用于直接关联(在示例中,它将lookup
和v
之间的直接关联放入环境中)。它显然不适用于传递关联,除非我多次调用它(我事先不知道它们有多少)。要回忆一下这个例子,在这个函数的末尾,我的环境列表应该是3
。
你能不能给我一个关于如何修改这个函数的提示,以便与传递关联一起工作?
提前致谢!
答案 0 :(得分:1)
首先,由于函数lookup
,augment_env_with_vars
和某些类型未知,因此很难给出精确的提示。
但是,根据您提供的内容进行猜测,可以这样做:
取1
type const = int
type var = string
type env = (var * const) list
datatype value = Const_p of const | Var_p of var
exception Not_found
fun lookup_env (e, v) =
case e of
[] => raise Not_found
| (a, b)::xs => if a = v then b else lookup_env (xs, v)
fun new_env (l, e) =
case l of
[] => e
| (a, b)::xs =>
case b of
Const_p _ => new_env (xs, e)
| Var_p b => new_env (xs, e @ [(a, lookup_env (e, b))])
(* test *)
val e = [("x", 1), ("y", 2), ("z", 3)]
val s = [("v", Var_p "z"), ("w", Var_p "v"), ("u", Var_p "w")]
val test = new_env (s, e)
结果1
val e = [("x",1),("y",2),("z",3)] : (string * int) list
val s = [("v",Var_p "z"),("w",Var_p "v"),("u",Var_p "w")]
: (string * value) list
val test = [("x",1),("y",2),("z",3),("v",3),("w",3),("u",3)]
: (var * int) list
但是,如果替换列表中的任何变量出现在其定义之前,new_env
将失败。要解决此问题,请在引用lookup_env
:
选择2
fun lookup_var (l, v) =
case l of
[] => v
| (a, b)::xs =>
case b of
Const_p _ => lookup_var (xs, v)
| Var_p b => lookup_var (if a = v then (l, b) else (xs, v))
fun new_env2 (l, e) =
case l of
[] => e
| (a, b)::xs =>
case b of
Const_p _ => new_env2 (xs, e)
| Var_p b => new_env2 (xs, e @ [(a, lookup_env (e, lookup_var (l, b)))])
(* test *)
val e = [("x", 1), ("y", 2), ("z", 3)]
val s2 = [("v", Var_p "z"), ("u", Var_p "w"), ("w", Var_p "v")]
val test2 = new_env2 (s2, e)
结果2
val e = [("x",1),("y",2),("z",3)] : (string * int) list
val s2 = [("v",Var_p "z"),("u",Var_p "w"),("w",Var_p "v")]
: (string * value) list
val test2 = [("x",1),("y",2),("z",3),("v",3),("u",3),("w",3)]
: (var * int) list
注意交换的" u"和" w"在第二个例子中。