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

发布于 2024-09-30 01:57:57 字数 1168 浏览 0 评论 0原文

我正在使用 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));;
验证它:Expr = Const 10
示例3:
<代码>> eval (If(Const 0,Const 3,Const 4));;
val it : Expr = Const 4

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

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

感谢所有帮助。

编辑:修正了代码中的一个拼写错误...之前我在可区分联合中使用了Mult而不是Minus。有趣的是我刚刚注意到这一点!

I'm using F# to create a lambda calculus. I am currently stuck trying to figure out how I would implement the fixed-point operator (also called Y combinator).

I think everything else is in order. Expressions are represented by the following discriminated union:

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

My eval function seems to work. The following examples all yield the expected results.
example 1:
> eval (Fun("x",Plus(Const 7,Var("x"))));;
val it : Expr = Fun ("x",Plus (Const 7,Var "x"))
example 2:
> eval (App(Fun("x",Plus(Const 7,Var("x"))),Const 3));;
val it : Expr = Const 10
example 3:
> eval (If(Const 0,Const 3,Const 4));;
val it : Expr = Const 4

But as I mentioned, I'm having difficulty implementing the fixed-point operator within my lambda calculus. It is defined here as:
Y = lambda G. (lambda g. G(g g)) (lambda g. G(g g))

Does anyone have any suggestions? I've looked at other questions regarding the Y combinator, but couldn't find anything that I was able to successfully adopt.

All help is appreciated.

Edit: Fixed a typo in the code... previously I had Mult instead of Minus in the discriminated union. Funny that I just noticed that!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半世蒼涼 2024-10-07 01:57:57

您所指的版本仅适用于惰性语言,如果您的语言不使用惰性求值策略,您将陷入无限循环。尝试翻译一下这个:

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

The version that you're referring to works only with a lazy language, and if your language isn't using a lazy evaluation strategy, you'll get stuck in an infinite loop. Try translating this:

Y = lambda G. (lambda g. G(lambda x. g g x)) (lambda g. G(lambda x. g g x))
栖竹 2024-10-07 01:57:57

据我记得,无类型 lambda 演算中有一整类 Y 组合器,但如果您的语言是严格类型的,那么即使是一个 Y 组合器也很难实现,尽管人们已经尝试在 ML 和 F# 中执行特殊情况。如果您的语言支持递归(lambda 演算不支持),那么它似乎不是很有用。看看 Stackoverflow 上标记为通用“函数式编程”或 ML 的有关该主题的讨论,我认为有一些见解:

Y-Combinator 实际示例

As far as I recall it, there are a whole class of Y Combinators in untyped lambda calculus, but it gets difficult to implement even one if your language is strictly typed, although people have tried to do special cases in ML and also F#. It doesn't seem to be very useful if your language supports recursion (which lambda calculus does not). Have a look at the discussions on that topic that Stackoverflow has seen flagged with generic "functional programming" or ML, I think there are some insights to be had:

Y-Combinator Practical Example

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文