您将如何在F#中实现beta缩减函数?

您将如何在F#中实现beta缩减函数?,f#,lambda-calculus,F#,Lambda Calculus,我正在用F#编写一个lambda演算,但我一直坚持实现beta缩减(用实际参数替换形式参数) 用法示例: (lambda n. n*2+3) 7 --> (n*2+3)[7/n] --> 7*2+3 因此,我很想听到一些关于其他人如何处理这件事的建议。任何想法都将不胜感激 谢谢 假设表达式的表示形式如下所示 type expression = App of expression * expression | Lambda of ident * exp

我正在用F#编写一个lambda演算,但我一直坚持实现beta缩减(用实际参数替换形式参数)

用法示例:

(lambda n. n*2+3) 7
--> (n*2+3)[7/n]
--> 7*2+3
因此,我很想听到一些关于其他人如何处理这件事的建议。任何想法都将不胜感激


谢谢

假设表达式的表示形式如下所示

type expression = App of expression * expression
                | Lambda of ident * expression
                (* ... *)
,您有一个函数
subst(x:ident)(e1:expression)(e2:expression):expression
,它用
e2
中的
e1
替换

let rec eval exp =
  match exp with
  (* ... *)
  | App (f, arg) -> match eval f with Lambda (x,e) -> eval (subst x arg e)
subst
功能应按如下方式工作:

对于函数应用程序,它应该在两个子表达式上递归调用自己

对于lambda,它应该在lambda的主体表达式上调用自己,除非lambda的参数名称等于您要替换的标识符(在这种情况下,您可以将lambda保留,因为标识符不能在其中任意位置自由显示)


对于一个变量,它应该返回未更改的变量或替换表达式,这取决于该变量的名称是否等于标识符。

BTW,我使用的示例来自对lambda演算的讨论,该讨论可在感谢sepp2K的响应中找到。你已经大致了解了我要做的事情的要点。但是我在完全实现上遇到的问题是beta_reduce。在这里,您已经注入了一个名为subst的函数,它执行与beta_reduce相同的操作,但没有解释subst是如何实现的。这让我的处境和以前一样。不过除此之外,你的代码很好地代表了我的样子。哦,还有一件事。。。您的应用程序案例不应该以eval(beta_reduce(x,e)arg)结尾吗?否则,我们不就是简单地返回函数而不实际应用它吗?@klactose:我更新了我的答案来解释如何实现
subst
。是的,它当然应该对替换的结果进行评估。愚蠢的错误。谢谢你的输入。当您建议subst应该在函数应用程序的两个子表达式上递归调用自己时,我不确定我是否理解您的意思。我的函数应用程序如下所示:App(expr1,expr2)。expr1应该是Lambda epression,而expr2是应该替换Lambda中变量的值。那么,如果subst接受3个参数,那么对于非lambda表达式的递归调用将使用哪些参数???抱歉回复太长!
let rec eval exp =
  match exp with
  (* ... *)
  | App (f, arg) -> match eval f with Lambda (x,e) -> eval (subst x arg e)