Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy Scala doesn't allow List.map _ and type signatures in REPL
    primarykey
    data
    text
    <h1>Background</h1> <p>I recently attended a beginner Scala meetup and we were talking about the difference between methods and functions (also discussed in-depth <a href="https://stackoverflow.com/questions/2529184/difference-between-method-and-function-in-scala">here</a>).</p> <p>For example:</p> <pre><code>scala&gt; val one = 1 one: Int = 1 scala&gt; val addOne = (x: Int) =&gt; x + 1 addOne: Int =&gt; Int = &lt;function1&gt; </code></pre> <p>This demonstrates that vals can not only have an integer type, but can have a function type. We can see the type in the scala repl:</p> <pre><code>scala&gt; :type addOne Int =&gt; Int </code></pre> <p>We can also define methods in objects and classes:</p> <pre><code>scala&gt; object Foo { | def timesTwo(op: Int) = op * 2 | } defined module Foo </code></pre> <p>And while a method doesn't have a type (but rather is has a type signature), we can lift it into a function to see what it is:</p> <pre><code>scala&gt; :type Foo.timesTwo &lt;console&gt;:9: error: missing arguments for method timesTwo in object Foo; follow this method with `_' if you want to treat it as a partially applied function Foo.timesTwo ^ scala&gt; :type Foo.timesTwo _ Int =&gt; Int </code></pre> <p>So far, so good. We even talked about how functions are actually objects with an apply method and how we can de-syntactic sugarify expressions to show this:</p> <pre><code>scala&gt; Foo.timesTwo _ apply(4) res0: Int = 8 scala&gt; addOne.apply(3) res1: Int = 4 </code></pre> <p>To me, this is quite helpful in learning the language because I can internalize what the syntax is actually implying.</p> <h1>Problematic Example</h1> <p>We did, however, run into a situation that we could not identify. Take, for example, a list of strings. We can map functions over the values demonstrating basic Scala collections and functional programming stuff:</p> <pre><code>scala&gt; List(1,2,3).map(_*4) res2: List[Int] = List(4, 8, 12) </code></pre> <p>Ok, so what is the type of List(1,2,3).map()? I would expect we would do the same :type trick in the repl:</p> <pre><code>scala&gt; :type List(1,2,3).map _ &lt;console&gt;:8: error: Cannot construct a collection of type Nothing with elements of type Nothing based on a collection of type List[Int]. List(1,2,3).map _ ^ </code></pre> <p>From the API definition, I know the signature is:</p> <pre><code>def map[B](f: (A) ⇒ B): List[B] </code></pre> <p>But there is also a full signature:</p> <pre><code>def map[B, That](f: (A) ⇒ B)(implicit bf: CanBuildFrom[List[A], B, That]): That </code></pre> <h1>Question</h1> <p>So there are two things I don't quite understand:</p> <ul> <li>Why doesn't the normal function lift trick work with List.map? Is there a way to de-syntactic sugar the erroneous statement to demonstrate what is going on?</li> <li>If the reason that the method can't be lifted is due to the full signature "implicit", what exactly is going on there? </li> </ul> <p>Finally, is there a robust way to inspect both types and signatures from the REPL?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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