List SML:扫描关系列表以获取所有可传递的关联
我有一个环境列表,它保存变量和值之间的关联,例如List SML:扫描关系列表以获取所有可传递的关联,list,sml,relation,smlnj,transitive-dependency,List,Sml,Relation,Smlnj,Transitive Dependency,我有一个环境列表,它保存变量和值之间的关联,例如env=[((“x”,1),(“y”,2),(“z”,3),…])。我还有另一个替换列表(由模式匹配控制函数返回),它保存变量和模式之间的关联,例如s=[(“v”,Var_p“z”),(“w”,Var_p“v”),(“u”,Var_p“w”),…]。让我们考虑第一对“代码>(V),VARYP P(Z))< /代码>:我的函数应该检查环境中对应于“代码>Z</CODE”的值,在 V和 Z < /代码>的值之间创建一个新的关联(即(v),3)< /代码
env=[((“x”,1),(“y”,2),(“z”,3),…])
。我还有另一个替换列表(由模式匹配控制函数返回),它保存变量和模式之间的关联,例如s=[(“v”,Var_p“z”),(“w”,Var_p“v”),(“u”,Var_p“w”),…]
。让我们考虑第一对“代码>(V),VARYP P(Z))< /代码>:我的函数应该检查环境中对应于“代码>Z</CODE”的值,在<代码> V和<代码> Z < /代码>的值之间创建一个新的关联(即<代码>(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
之间的直接关联放入环境中)。它显然不适用于传递关联,除非我多次调用它(我事先不知道它们有多少)。回想一下这个例子,在这个函数结束时,我的环境列表应该是env=[((“x”,1),(“y”,2),(“z”,3),(“v”,3),(“w”,3),(“u”,3),…]
您能给我一个关于如何修改此函数的提示,使其也能很好地处理传递关联吗
提前谢谢 首先,很难给出精确的提示,因为函数
lookup
,使用变量
增强环境,并且某些类型是未知的
但是,根据您提供的信息,可以这样做:
取1
结果1
但是,如果替换列表中的任何变量位于其定义之前,new_env
将失败。要解决此问题,只需在参考lookup\u env
之前扫描替换列表:
第二次拍摄
结果2
注意第二个示例中交换的“u”和“w”
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)
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
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)
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