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
    的任何表达式

  • 我假设
    FunExpr
    是一个lambda。例如,表达式(λx.x+y)5被编码为
    ApplyExpr(FunExpr(“x”,?,Int,Int,PlusExpr(VarExpr“x”,VarExpr“y”)),IntExpr 5)

    我不确定
    FunExpr
    中的第二个字符串参数用于什么。可能是命名函数还是匿名函数?这可能会使其中一个参数成为字符串选项

    如果
    FunExpr
    是lambda,那么x应该被视为表达式(λx.x+y)x中的自由变量还是绑定变量?显然,x在不同的时间都存在,但是函数应该返回什么呢

  • 您有一个很好的基本策略:一个递归函数,它遍历表达式并保留在子表达式中看到的变量的“聚合列表”。如果再次看到表达式,则不会第二次包含该表达式

    但是如果一个变量出现在单独的子表达式中,它们都包括在内, 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
在这种情况下,想想

  • 何时更新绑定集和自由集,以及
  • 如果/何时使用返回的绑定集和自由集
如何应用FuncExpr

我不明白那个问题。如果您指的是如何在函数中编写
FunExpr
子句,则必须指定它试图实现的目标,以获得任何合理的反馈。到目前为止,对于这些构造器应该做什么,我这边有一些猜测

我使用什么作为典型类型


正如Ionuț所说,类型对于该函数的输出并不重要。

代码中的即时错误:您希望
VarExpr(a)=if…
成为
VarExpr a=>if…
aggr_List
未绑定的原因是变量名用小写字母L书写,但始终用大写字母L引用。此外,您实际上没有写问题。谢谢您,这是一个愚蠢的错误。我编辑了这篇文章以包含一个问题什么是
FuncExpr
?它是否用于将表达式中的某些变量绑定到其第5个参数中?我试图理解一个变量是自由的意味着什么。如果您提供一个重要的
expr
值示例,以及
isFV