Type deduction for function pointers

  Kiến thức lập trình

This answer explains that many functions with the same signature have different types.
If we have to consider these functions with a common type, even an approximative coercion on one of them is enough to make the compiler consider that all the functions have the same type.

In the first loop of the following example, if we withdraw the as fn(_, _) -> _ coercion, the compiler complains for the reason explained in the answer referenced at the beginning of this question.

However, in the second loop, no coercion is needed to make the compiler consider that all the functions have the same type; this does not match the reason given above…
Question: why does the presence or absence of a tuple change in the type deduction of the function pointers?

In the third loop, we can avoid introducing the coercion and still obtain the expected tuples thanks to a trick, but it is not very convenient (the various members of a tuple are far from each other).
Subsidiary question: isn’t there a way to conveniently transform the first loop without needing the coercion?

fn add(
    l: i32,
    r: i32,
) -> i32 {
    l + r
}

fn multiply(
    l: i32,
    r: i32,
) -> i32 {
    l * r
}

fn main() {
    // /a/54629954/11527076
    for (name, operation) in [
        ("add", add as fn(_, _) -> _ /* coercion needed */),
        ("multiply", multiply),
    ] {
        println!("{} ~~> {}", name, operation(10, 2));
    }

    for operation in [add /* no coercion ??? */, multiply] {
        println!("~~> {}", operation(10, 2));
    }

    for (name, operation) in
        std::iter::zip(["add", "multiply"], [add, multiply])
    {
        println!("{} ~~> {}", name, operation(10, 2));
    }
}
/*
add ~~> 12
multiply ~~> 20
~~> 12
~~> 20
add ~~> 12
multiply ~~> 20
*/

LEAVE A COMMENT