Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>To complement the other answers, here are some examples showing why you get the "missing parameter type" in some cases when using '_' as a placeholder parameter.</p> <p>Scala's type inference considers the 'expected' type of an expression based on its context. If there is no context, it cannot infer the type of the parameters. Notice in the error message the first and second instances of <code>_</code> are replaced with the compiler generated identifiers <code>x$1</code> and <code>x$2</code>.</p> <pre><code>scala&gt; _ + _ &lt;console&gt;:5: error: missing parameter type for expanded function ((x$1, x$2) =&gt; x$1.$plus(x$2)) _ + _ ^ &lt;console&gt;:5: error: missing parameter type for expanded function ((x$1: &lt;error&gt;, x$2) =&gt; x$1.$plus(x$2)) _ + _ ^ </code></pre> <p>Adding a type ascription to the entire expression provides enough context to help the inferencer: </p> <pre><code>scala&gt; (_ + _) : ((Int, Int) =&gt; Int) res3: (Int, Int) =&gt; Int = &lt;function2&gt; </code></pre> <p>Alternatively, you can add a type ascription to each parameter placeholder:</p> <pre><code>scala&gt; (_: Int) + (_: Int) res4: (Int, Int) =&gt; Int = &lt;function2&gt; </code></pre> <p>In the function call below with type arguments provided, the context is unambigous and the function type is inferred.</p> <pre><code>scala&gt; def bar[A, R](a1: A, a2: A, f: (A, A) =&gt; R) = f(a1, a2) bar: [A,R](a1: A,a2: A,f: (A, A) =&gt; R)R scala&gt; bar[Int, Int](1, 1, _ + _) res5: Int = 2 </code></pre> <p>However, if we ask the compiler to infer the type parameters, if fails:</p> <pre><code>scala&gt; bar(1, 1, _ + _) &lt;console&gt;:7: error: missing parameter type for expanded function ((x$1, x$2) =&gt; x$1.$plus(x$2)) bar(1, 1, _ + _) ^ &lt;console&gt;:7: error: missing parameter type for expanded function ((x$1: &lt;error&gt;, x$2) =&gt; x$1.$plus(x$2)) bar(1, 1, _ + _) ^ </code></pre> <p>We can help it, though, by currying the parameter lists. Here, the arguments to the first parameter list <code>(1, 1)</code>, tell the inference that the type parameter <code>A</code> should be <code>Int</code>. It then knows that the type of the argument <code>f</code> must be <code>(Int, Int) =&gt; ?)</code>, and the return type <code>R</code> is inferred as <code>Int</code>, the result of integer addition. You will see the same approach used in <code>Traversable.flatMap</code> in the standard library.</p> <pre><code>scala&gt; def foo[A, R](a1: A, a2: A)(f: (A, A) =&gt; R) = f(a1, a2) foo: [A,R](a1: A,a2: A)(f: (A, A) =&gt; R)R scala&gt; foo[Int, Int](1, 1) { _ + _ } res1: Int = 2 scala&gt; foo(1, 1) { _ + _ } res0: Int = 2 </code></pre>
 

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