Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I'll start by simplifying a bit. Suppose I have a function <code>f</code>. I don't know it's arity in advance, and I don't care about what it returns. I want to wrap it with some functionality and get a function with the same argument types. I also don't care what this resulting function returns, so I may as well have it return <code>Unit</code>.</p> <p>You could write a bunch (well, 22) of functions like the following:</p> <pre><code>def wrap[A](f: A =&gt; Unit): A =&gt; Unit = ??? def wrap[A, B](f: (A, B) =&gt; Unit): (A, B) =&gt; Unit = ??? def wrap[A, B, C](f: (A, B, C) =&gt; Unit): (A, B, C) =&gt; Unit = ??? </code></pre> <p>But you don't want to.</p> <p>Shapeless can definitely help you solve this problem more generically:</p> <pre><code>def wrap[F, A &lt;: HList](f: F)( implicit h: FnHListerAux[F, A =&gt; Unit], u: FnUnHListerAux[A =&gt; Unit, F] ): F = { (args: A) =&gt; println("Before!"); f.hlisted(args); println("After!") }.unhlisted </code></pre> <p>Which gives us:</p> <pre><code>scala&gt; def f(i: Int, s: String) { println(s * i) } f: (i: Int, s: String)Unit scala&gt; val wf = wrap(f _) wf: (Int, String) =&gt; Unit = &lt;function2&gt; scala&gt; wf(3, "ab") Before! ababab After! </code></pre> <p>Note that <code>f</code> could return something other than <code>Unit</code> and this would still work, since everything in Scala is a <code>Unit</code> and the <code>FunctionN</code> traits are covariant in their return type.</p> <p>Applying this approach to your code, we get the following:</p> <pre><code>def async[F, A &lt;: HList]( shell: Shell, success: F, failure: FunctionTypes.Failure )( implicit h: FnHListerAux[F, A =&gt; Unit], u: FnUnHListerAux[A =&gt; Unit, F] ): F = { (args: A) =&gt; require(shell != null, "Shell cannot be null") require(shell.getDisplay() != null, "The shell must have a display") val display = shell.getDisplay() display.asyncExec(new Runnable() { def run(): Unit = { try { success.hlisted(args) } catch { case e: Throwable =&gt; failure(e) } } }) }.unhlisted </code></pre> <p>No <code>dummy</code> required.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload