This question is more complex than Closure as function parameter “cannot infer an appropriate lifetime due to conflicting requirements”.
There's a recursive closure which move environmental variable into it.
The code below works, tool is a grab-bag of useful functions for functional programming includes making recursive closure:
extern crate tool;
use tool::prelude::*;
use std::cell::Cell;
fn main() {
let a = Cell::new(false);
let fib = fix(move |f, x| {
a.set(true);
if x == 0 || x == 1 {
x
} else {
// `f` is `fib`
f(x - 1) + f(x - 2)
}
});
println!("{}", fib(10));
}
I want to know is it possible to pass that closure to a function, then call that function in that closure, the code below throws an error.
extern crate tool;
use tool::prelude::*;
use std::cell::RefCell;
fn main() {
let a = RefCell::new(false);
let fib = fix(move |f, x| {
*a.borrow_mut() = true;
if x == 0 || x == 1 {
x
} else {
// `f` is `fib`
b(Box::new(f), x - 1) + f(x - 2)
}
});
fn b (c: Box<Fn(u64) -> u64>, n: u64) -> u64 {
c(n)
}
println!("{}", b(Box::new(fib), 10));
}
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:14:24
|
14 | b(Box::new(f), x - 1) + f(x - 2)
| ^
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 8:19...
--> src/main.rs:8:19
|
8 | let fib = fix(move |f, x| {
| ___________________^
9 | | *a.borrow_mut() = true;
10 | | if x == 0 || x == 1 {
11 | | x
... |
15 | | }
16 | | });
| |_____^
= note: ...so that the expression is assignable:
expected &dyn std::ops::Fn(u64) -> u64
found &dyn std::ops::Fn(u64) -> u64
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn std::ops::Fn(u64) -> u64 + 'static)>
found std::boxed::Box<dyn std::ops::Fn(u64) -> u64>
Box
seems to work for me. Is that what you want? – rodrigofn
,dyn Fn
and maybeimpl Fn
. I'm not familiar withtool
but messing around, this version compiles. – rodrigo