如何在F#中实现定点运算符(Y组合子)?

时间:2010-11-03 07:58:29

标签: f# fixed-point lambda-calculus y-combinator

我正在使用F#创建一个lambda演算。我目前正试图弄清楚如何实现定点运算符(也称为Y组合器)。

我认为其他一切都是有序的。表达式由以下区分联合表示:

type Expr =
 | Const of int
 | Plus  of Expr * Expr
 | Times of Expr * Expr
 | Minus of Expr * Expr
 | Div   of Expr * Expr
 | Neg   of Expr
 | Var   of string
 | Fun   of string * Expr
 | App   of Expr * Expr
 | If    of Expr * Expr * Expr

我的eval功能似乎有效。以下示例均得出预期结果 例1:
> eval (Fun("x",Plus(Const 7,Var("x"))));;
val it : Expr = Fun ("x",Plus (Const 7,Var "x"))
例2:
> eval (App(Fun("x",Plus(Const 7,Var("x"))),Const 3));;
val it : Expr = Const 10
例3:
> eval (If(Const 0,Const 3,Const 4));;
val it : Expr = Const 4

但正如我所提到的,我在lambda演算中实现定点运算符时遇到了困难。将here定义为:
Y = lambda G. (lambda g. G(g g)) (lambda g. G(g g))

有没有人有任何建议?我已经查看了有关Y组合器的其他问题,但找不到任何我能够成功采用的问题。

感谢所有帮助。

编辑:修正了代码中的拼写错误...之前我在歧视联盟中有Mult而不是Minus。有趣的是我刚注意到了!

2 个答案:

答案 0 :(得分:4)

您所指的版本仅适用于懒惰语言,如果您的语言未使用惰性评估策略,您将陷入无限循环。尝试翻译这个:

Y = lambda G. (lambda g. G(lambda x. g g x)) (lambda g. G(lambda x. g g x))

答案 1 :(得分:1)

据我所知,在无类型的lambda演算中有一整类Y组合器,但如果你的语言是严格打字的话,即使有一个很难实现,尽管人们试图在ML中做特殊情况。 F#。如果您的语言支持递归(lambda演算不支持),它似乎没有用。看看Stackoverflow已经看到标记为泛型“函数式编程”或ML的那个主题的讨论,我认为有一些见解:

Y-Combinator Practical Example