How to explicitly call a generic function that trait bound on `Fn` (or `FnMut` or `FnOnce`)?

For non-Fn trait is pretty straightforward:

fn print<T>(t: T)
where
    T: std::fmt::Debug,
{
    println!("print: {:?}", t);
}

fn main() {
    print::<f64>(1.618);
    print::<String>("hello rust".to_owned());
    print::<(&str, i32)>(("bfg", 9000));
}

But how about Fn, FnMut and FnOnce?

fn apply_to_3<F>(f: F) -> i32
where
    F: Fn(i32) -> i32,
{
    f(3)
}

fn main() {
    apply_to_3(|x| 2 * x); // implicit
    apply_to_3::<???>(|x| 2 * x); // explicit
}

With a closure, you can't. The type of a closure cannot be named.

If you have something that you can coerce to a function pointer (fn) type, then you can write apply_to_3::<fn(i32) -> i32>(|x| 2 * x). (This of course only works with function items and non-capturing closures, because capturing closures can't be represented by a simple function pointer.)

1 Like

If you need to pass other type parameters explicitly, you can explicitly leave the one for the closure inferred with an underscore.

E. g.

fn apply<T, F>(f: F, x: T) -> T
where
    F: Fn(T) -> T,
{
    f(x)
}

fn main() {
    let y = apply::<u64, _>(|x| 2 * x, 42);
}

(playground)

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.