title: How to store impl Fn in an enum type?
body: <p>I had a use-case where I wanted to store a function in an enum type</p>
  <pre class="lang-rust prettyprint-override"><code>#[derive(Debug)]
  enum RispErr {
      Reason(String),
  }
  
  #[derive(Clone)]
  enum RispExp {
      Bool(bool),
      Symbol(String),
      Number(f64),
      List(Vec&lt;RispExp&gt;),
      Func(fn(&amp;Vec&lt;RispExp&gt;) -&gt; Result&lt;RispExp, RispErr&gt;),
  }
  </code></pre>
  <p>In one case, I wanted to create a higher order function to generate these</p>
  <pre class="lang-rust prettyprint-override"><code>// simplifying this for the question
  // shortening this for brevity
  fn make_tonicity_checker(
      tone_fn: fn(f64, f64) -&gt; bool,
  ) -&gt; impl Fn(&amp;Vec&lt;RispExp&gt;) -&gt; Result&lt;RispExp, RispErr&gt; {
      return move |args: &amp;Vec&lt;RispExp&gt;| -&gt; Result&lt;RispExp, RispErr&gt; {
          tone_fn(1.0, 2.0); // need to use this
          return Ok(RispExp::Bool(true));
      };
  }
  </code></pre>
  <p>I come across errors though when I tried to use the higher order function</p>
  <pre class="lang-rust prettyprint-override"><code>fn f() -&gt; () {
      RispExp::Func(make_tonicity_checker(|a, b| a &gt; b));
  }
  </code></pre>
  <pre class="lang-none prettyprint-override"><code>mismatched types
  
  expected fn pointer, found opaque type
  
  note: expected type `for&lt;'r&gt; fn(&amp;'r std::vec::Vec&lt;RispExp&gt;) -&gt; std::result::Result&lt;RispExp, RispErr&gt;`
           found type `impl for&lt;'r&gt; std::ops::Fn&lt;(&amp;'r std::vec::Vec&lt;RispExp&gt;,)&gt;`rustc(E0308)
  main.rs(93, 5): expected fn pointer, found opaque type
  </code></pre>
  <p>I dug deeper and realized that function pointers cannot capture the environment, and hence the error. I tried</p>
  <pre class="lang-rust prettyprint-override"><code>Func(Fn(&amp;Vec&lt;RispExp&gt;) -&gt; Result&lt;RispExp, RispErr&gt;),
  </code></pre>
  <p>but, realized this fails too, as it doesn't have a size known at compile time. with some googling, I found that I could potentially pass this in as a type parameter</p>
  <pre><code>#[derive(Clone)]
  enum RispExp&lt;T&gt;
  where
      T: Fn(&amp;Vec&lt;RispExp&lt;T&gt;&gt;) -&gt; Result&lt;RispExp&lt;T&gt;, RispErr&gt;,
  {
      Bool(bool),
      Symbol(String),
      Number(f64),
      List(Vec&lt;RispExp&lt;T&gt;&gt;),
      Func(T),
  }
  </code></pre>
  <p>but then, in all places where I accept <code>RispExp</code>, I would need to provide this type parameter. That seems a bit annoying to do, because I would have to repeat <code>where T: Fn(&amp;Vec&lt;RispExp&lt;T&gt;&gt;) -&gt; Result&lt;RispExp&lt;T&gt;, RispErr&gt;,</code> everywhere.</p>
  <p>I could do <code>Func(Box&lt;Fn(&amp;Vec&lt;RispExp&gt;) -&gt; Result&lt;RispExp, RispErr&gt;&gt;)</code>, but then <code>dyn fn</code> doesn't implement <code>Clone</code>.</p>
  <p>What would you recommend I do?</p>