Pass Generic Function as argument
<p>I would like to be able to pass a generic function to another function (in this case a closure), without losing the &quot;genericness&quot; of the passed function. Since that's a pretty convoluted statement, here's an example:</p>
<pre><code>use std::fmt::Debug;

fn test&lt;F, I: Debug&gt;(gen: F) where F: Fn(fn(I) -&gt; I) -&gt; I {
    fn input&lt;I: Debug&gt;(x: I) -&gt; I {
        x
    }
    
    println!(&quot;{:?}&quot;, gen(input));
}

fn main() {
    test(|input| {
        input(10);
        input(10.0)
    });
}
</code></pre>
<p>This will not compile, because the value of <code>input</code> is type inferenced and no longer generic.</p>
<p>Full error:</p>
<pre><code>&lt;anon&gt;:14:15: 14:19 error: mismatched types:
 expected `_`,
    found `_`
(expected integral variable,
    found floating-point variable) [E0308]
&lt;anon&gt;:14         input(10.0)
                        ^~~~
</code></pre>
<p>Is such a thing possible in rust?</p>
<p>edit:</p>
<p>Based on the solutions given, I've used the following to solve a similar problem:</p>
<pre><code>#![feature(unboxed_closures)]
#![feature(fn_traits)]

use std::ops::Fn;
use std::ops::Add;
use std::ops::FnMut;

use std::fmt::Debug;

struct Builder;

impl Builder {
    pub fn build&lt;A: Add&lt;B&gt;, B: Add&lt;A&gt;&gt;(&amp;self) -&gt; fn(A, B) -&gt; &lt;A as std::ops::Add&lt;B&gt;&gt;::Output {
        fn c&lt;A: Add&lt;B&gt;, B: Add&lt;A&gt;&gt;(a: A, b: B) -&gt; &lt;A as std::ops::Add&lt;B&gt;&gt;::Output {
            a + b
        }
        
        return c;
    }
}

impl&lt;A: Add&lt;B&gt;, B: Add&lt;A&gt;&gt; Fn&lt;(A, B)&gt; for Builder {
    extern &quot;rust-call&quot; fn call(&amp;self, args: (A, B)) -&gt; &lt;A as std::ops::Add&lt;B&gt;&gt;::Output {
        let (a1, a2) = args;
        self.build()(a1, a2)
    }
}

impl&lt;A: Add&lt;B&gt;, B: Add&lt;A&gt;&gt; FnMut&lt;(A, B)&gt; for Builder {
    extern &quot;rust-call&quot; fn call_mut(&amp;mut self, args: (A, B)) -&gt; &lt;A as std::ops::Add&lt;B&gt;&gt;::Output {
        let (a1, a2) = args;
        self.build()(a1, a2)
    }
}

impl&lt;A: Add&lt;B&gt;, B: Add&lt;A&gt;&gt; FnOnce&lt;(A, B)&gt; for Builder {
    type Output = &lt;A as std::ops::Add&lt;B&gt;&gt;::Output;
    extern &quot;rust-call&quot; fn call_once(self, args: (A, B)) -&gt; &lt;A as std::ops::Add&lt;B&gt;&gt;::Output {
        let (a1, a2) = args;
        self.build()(a1, a2)
    }
}

fn test&lt;F, I: Debug&gt;(gen: F) where F: Fn(Builder) -&gt; I {
    let b = Builder;
    println!(&quot;{:?}&quot;, gen(b));
}

fn main() {
    test(|builder| {
        builder(10, 10);
        builder(10.1, 10.0)
    });
}
</code></pre>