gpt4 book ai didi

lambda - 如何返回接收 lambda/函数的匿名函数/lambda?

转载 作者:行者123 更新时间:2023-11-29 08:27:22 30 4
gpt4 key购买 nike

可以使用 lambda 和函数创建有序对(Lisp 中的缺点),如 Use of lambda for cons/car/cdr definition in SICP 所示。

它也适用于 Python:

def cons(x,y):
return lambda m:m(x,y)
def car(z):
return z(lambda x, y: x)
def cdr(z):
return z(lambda x, y: y)

当我用静态类型语言 Rust 实现它时:

fn cons(x: i32, y: i32) -> Box<Fn() -> Fn(i32, i32)> {
Box::new(move |m| m(x, y));
}

它显示错误:

error: the type of this value must be known in this context
--> src/main.rs:2:23
|
2 | Box::new(move |m| m(x, y));
| ^^^^^^^

error[E0308]: mismatched types
--> src/main.rs:1:54
|
1 | fn cons(x: i32, y: i32) -> Box<Fn() -> Fn(i32, i32)> {
| ______________________________________________________^ starting here...
2 | | Box::new(move |m| m(x, y));
3 | | }
| |_^ ...ending here: expected box, found ()
|
= note: expected type `Box<std::ops::Fn() -> std::ops::Fn(i32, i32) + 'static + 'static>`
= note: found type `()`

如何定义m的类型?

最佳答案

第一个小错误:您在函数体的末尾添加了一个分号。这意味着

Box::new(move |m|m(x,y));

只是一个没有副作用的语句,很像 3 + 4; .当你删除分号时,你会得到一个更好的编译器错误,因为现在编译器开始将你的表达式类型与返回类型连接起来。

说到:不幸的是,您的返回类型是错误的。你想要的是捕获两个参数 xy并返回一个接受另一个闭包的闭包,然后使用两个参数调用该闭包。此代码有效:

fn cons(x: i32, y: i32) ->  Box<Fn(&Fn(i32, i32))> {
Box::new(move |m| m(x, y))
}

如你所见,返回的闭包类型是:Fn(&Fn(i32, i32)) .接受另一个闭包作为参数的闭包。你可以像这样使用它:

let fun = cons(3, 7);
fun(&|x, y| println!("{}", x));

但是我们这里有两个问题:

  1. 为什么引用 & ? Rust 中的闭包是 Voldemort 类型,您只能根据它们实现的特征(例如 Fn 特征)来谈论它们。通常,您有两种方法来接受实现特征 Foo 的任意类型: 使用静态分派(dispatch)和单态化 ( fn bar<T: Foo>(x: T) ) 或作为特征对象并使用动态分派(dispatch) ( fn bar(x: &Foo) )。但是,您已经返回了一个特征对象 ( Box<Fn(...)> ),并且特征对象不能有泛型方法(由于各种原因它们不能单态化)。这意味着您需要自己接受特征对象,并且由于特征对象未确定大小,因此它们需要隐藏在引用或类似 Box 的后面。 .

  2. 闭包不返回任何东西!正确,因为这又需要单态化,因为 Rust 是静态类型的。您展示/链接的示例是动态类型语言,其中这些不是问题。在 Rust 中,这是一个不同的故事。您可以使用 Box<Any> 在 Rust 中伪造动态类型或类似的东西。但这并不是真正的惯用语,应该避免。 也许你真的需要它,但也许你还想在 Rust 中错误地使用其他语言的模式,而应该以更生疏的方式思考你的问题;-)

关于lambda - 如何返回接收 lambda/函数的匿名函数/lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42606536/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com