Types 返回SML中自由(未绑定)变量的列表
我已经创建了自己的数据类型:Types 返回SML中自由(未绑定)变量的列表,types,sml,abstract-data-type,free-variable,Types,Sml,Abstract Data Type,Free Variable,我已经创建了自己的数据类型: datatype typ = Bool | Int | Arrow of typ*typ; (* i.e., Arrow(argType, returnType) *) (* diMLazy expressions *) datatype expr = TrueExpr | FalseExpr | IntExpr of int | VarExpr of string
datatype typ = Bool | Int | Arrow of typ*typ;
(* i.e., Arrow(argType, returnType) *)
(* diMLazy expressions *)
datatype expr = TrueExpr
| FalseExpr
| IntExpr of int
| VarExpr of string
| PlusExpr of expr*expr
| LessExpr of expr*expr
| IfExpr of expr*expr*expr
| ApplyExpr of expr*expr
| FunExpr of string*string*typ*typ*expr
使用这些,我需要编写一个函数isFV,它返回传递到函数中的任何自由变量的列表。
到目前为止,我的代码是:
fun isFV (exp:expr) =
let
val bound_list = [];
(*Contains returns true if x:string is within a string list.*)
fun contains (i:string, str_list:string list) =
foldr(fn (x,y) => i = x orelse y) false str_list;
fun anaExp (ex:expr, aggr_list:string list) =
case ex of
TrueExpr => []
| FalseExpr => []
| IntExpr (a) => []
| PlusExpr (a, b) => anaExp(a,aggr_list) @ anaExp(b,aggr_list)
| LessExpr (a, b) => anaExp(a,aggr_list) @ anaExp(b,aggr_list)
| IfExpr (a, b, c) => anaExp(a,aggr_list) @ anaExp(b,aggr_list) @ anaExp(c,aggr_List)
| ApplyExpr (a,b) => anaExp(a,aggr_list) @ anaExp(b,aggr_list)
| FunExpr (a, b, c, d, e) => ??????
| VarExpr (a) = if(contains (a,aggr_List)) then [] else [a]
in
anaExp(exp, bound_list)
end
anaExp的初衷是获取一个空列表并递归地调用自身,直到获得一个VarExpr术语。然后它会将其添加到aggr_列表中
如何应用FuncExpr?我知道使用VarExpr作为字符串类型,但是我使用什么作为类型类型呢?目前我有:
| FunExpr (a, b, c, d, e) => anaExp(VarExpr(a),aggr_list) @ anaExp(VarExpr(b),aggr_list)
@ anaExp(c,aggr_list) @ anaExp(d,aggr_list) @ anaExp(e,aggr_list)
但是我们知道,将一个typ传递到anaExp将导致一个类型错误(c和d)。FunExpr案例应该使用函数所取参数的名称来扩充
aggr\u list
。我假定FunExpr
的第一个string
是函数名,第二个string
是参数名。然后应将此参数名称添加到绑定变量列表中,即,aggr_list
,然后在函数体上递归。您可以安全地忽略此问题的函数类型
[…]一个函数isFV,返回传递到函数中的任何自由变量的列表
以下是一些反馈:
- 对于返回列表的函数来说,这听起来是个坏名字。这听起来像是判断某个事物是否是自由变量的谓词函数的好名字。此外,功能似乎有点不清楚。我假设它是馈送到
的任何表达式isFV
- 我假设
是一个lambda。例如,表达式(λx.x+y)5被编码为FunExpr
我不确定ApplyExpr(FunExpr(“x”,?,Int,Int,PlusExpr(VarExpr“x”,VarExpr“y”)),IntExpr 5)
中的第二个字符串参数用于什么。可能是命名函数还是匿名函数?这可能会使其中一个参数成为字符串选项 如果FunExpr
是lambda,那么x应该被视为表达式(λx.x+y)x中的自由变量还是绑定变量?显然,x在不同的时间都存在,但是函数应该返回什么呢FunExpr
- 您有一个很好的基本策略:一个递归函数,它遍历表达式并保留在子表达式中看到的变量的“聚合列表”。如果再次看到表达式,则不会第二次包含该表达式
但是如果一个变量出现在单独的子表达式中,它们都包括在内,
e、 g.
将生成PlusExpr(VarExpr“a”,VarExpr“a”)
,因为在调用子表达式之间不会更新聚合列表[“a”]@[“a”]
- 您似乎没有区分自由变量和绑定变量。假设一个
实际上创建了一个绑定变量,那么递归函数的聚合状态必须稍微复杂一点,才能抓住区别: 变量之所以是自由变量,不仅仅是因为它是一个变量,而是因为它在当前范围内没有作为绑定变量出现(由一组当前绑定变量维护)FunExpr
- 使用集合类型可能比使用列表类型更容易。根据SML编译器的不同,可能存在内置的集合类型。例如,在SML/NJ中,有一个基于列表的集合函子:
structure Set = ListSetFn(struct type ord_key = string val compare = String.compare end)
fun getVars expr0 =
let
fun gv bound free expr =
case expr of
TrueExpr => (bound, free)
| FalseExpr => (bound, free)
| IntExpr => (bound, free)
| VarExpr var => if Set.member (var, bound)
then ...
else ...
| PlusExpr (a, b) =>
let val (bound', free') = gv bound free a
val (bound'', free'') = gv ... ... b
in (..., ...) end
| LessExpr (a, b) => ...
| IfExpr (a, b, c) => ...
| ApplyExpr (a, b) => ...
| FunExpr (var, whatIsThis, _, _, a) =>
let val bound' = Set.add (bound, var)
val (bound'', free'') = gv ... ... a
in (..., ...) end
val (bound, free) = gv Set.empty Set.empty expr0
in
...
end
在这种情况下,想想
- 何时更新绑定集和自由集,以及
- 如果/何时使用返回的绑定集和自由集
FunExpr
子句,则必须指定它试图实现的目标,以获得任何合理的反馈。到目前为止,对于这些构造器应该做什么,我这边有一些猜测
我使用什么作为典型类型
正如Ionuț所说,类型对于该函数的输出并不重要。代码中的即时错误:您希望
VarExpr(a)=if…
成为VarExpr a=>if…
。aggr_List
未绑定的原因是变量名用小写字母L书写,但始终用大写字母L引用。此外,您实际上没有写问题。谢谢您,这是一个愚蠢的错误。我编辑了这篇文章以包含一个问题什么是FuncExpr
?它是否用于将表达式中的某些变量绑定到其第5个参数中?我试图理解一个变量是自由的意味着什么。如果您提供一个重要的expr
值示例,以及isFV