Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala, different behaviour when calling `map(f)` vs `map(v => f(v))`

Tags:

scala

I get a different behaviour when calling map(f) vs map(v => f(v)). Why?

libraryDependencies += "com.lihaoyi" %% "pprint" % "0.4.1"

case class Entry(id: Int, text: String)
val entry = Entry(1, "hello")

def toPrettyString[T](o: T)(implicit pp: pprint.PPrint[T]) =
  pprint.tokenize(o)(pp).mkString

println(toPrettyString(entry))                            // I get Entry(1, "hello"), as expected

List(entry).map(toPrettyString).foreach(println)          // I get Entry(1,hello), not what I want
List(entry).map(e => toPrettyString(e)).foreach(println)  // I get Entry(1, "hello"), as expected
like image 835
David Portabella Avatar asked Oct 14 '16 17:10

David Portabella


1 Answers

Eta-expansion (which turns the method toPrettyString used as a value into an anonymous function) happens before type parameter inference, you can think of it as equivalent to

def toPrettyString1[T]: T => String = 
  (x: T) => toPrettyString(x)

List(entry).map(toPrettyString1)

in toPrettyString1, the default implicit instance of PPrint, which just calls toString, has to be chosen.

In List(entry).map(e => toPrettyString(e)), type of e is inferred to be Entry and so the macro generates the correct implicit.

https://issues.scala-lang.org/browse/SI-7641

like image 146
Alexey Romanov Avatar answered Nov 15 '22 09:11

Alexey Romanov