【发布时间】:2023-04-06 20:27:01
【问题描述】:
假设我有一个高阶函数,比如composition from this answer:
fn compose<A, B, C, G, F>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
move |x| g(f(x))
}
我想部分应用它,如
fn id<T>(x: &T) -> &T { x }
fn compose_with_id<T, U, F>(f: F) -> impl Fn(&T) -> U
where
F: Fn(&T) -> U
{
compose(id, f)
}
这不会编译。 IIUC 的问题是,在compose 调用站点,我们必须用特定类型替换A(包括特定生命周期),但返回值需要为所有'a 实现Fn(&'a T) -> U。我尝试将对compose 的调用移动到闭包中:
fn compose_with_id<T, U, F>(f: F) -> impl Fn(&T) -> U
where
F: Fn(&T) -> U
{
move |t| compose(id, f)(t)
}
这也无法编译。现在的问题是compose 试图在每次调用结果函数时获取f 的所有权。我没有办法修复compose_with_id(不坚持F: Copy); compose 拥有f 的所有权,这只能发生一次,所以我们必须选择一个生命周期,但返回值需要处理任何生命周期。
我们可以创建一个compose 的变体,用于引用:
fn compose<A, B, C, G, F>(f: F, g: G) -> impl Fn(&A) -> C
where
F: Fn(&A) -> &B,
G: Fn(&B) -> C,
{
move |x| g(f(x))
}
(其返回值具有 HRTB)但不能用于非参考输入。
如何定义compose,使其可以部分应用于带有或不带有参考输入的不可复制函数?
【问题讨论】:
标签: rust