karjan
karjan

Reputation: 1016

Scala underscore usage in lambdas

I'm having issue figuring out difference in codes below.

  val l1 = List('a', 'b')
  val l2 = List(1, 2, 3, 4)
  val x = l1.flatMap(v1 => l2.map(b => "" +  v1 + b))
  print(x)
//List(a1, a2, a3, a4, b1, b2, b3, b4)

.

  val l1 = List('a', 'b')
  val l2 = List(1, 2, 3, 4)
  val x = l1.flatMap(v1 => l2.map(_ => "" +  v1 + _))
  print(x)
//List(One$$$Lambda$13/398887205@1554909b, One$$$Lambda$13/398887205@6bf256fa, One$$$Lambda$13/398887205@6cd8737, One$$$Lambda$13/398887205@22f71333, One$$$Lambda$13/398887205@13969fbe, One$$$Lambda$13/398887205@6aaa5eb0, One$$$Lambda$13/398887205@3498ed, One$$$Lambda$13/398887205@1a407d53)

Should't _ and b behave the same?

Upvotes: 0

Views: 268

Answers (2)

Mahesh Chand
Mahesh Chand

Reputation: 3250

Second version code is creating a partially applied function. Here _ just tells there will be value in future.

For example,

scala> val x = l1.flatMap{ v1 => 
     |             l2.map(_ => "" +  v1 + _)
     | }
x: List[Any => String] = List($$Lambda$1150/1830704523@5401976b, $$Lambda$1150/1830704523@22f9cea5, $$Lambda$1150/1830704523@7fb2e8d3, $$Lambda$1150/1830704523@601f58a3, $$Lambda$1150/1830704523@387d2104, $$Lambda$1150/1830704523@541d5c48, $$Lambda$1150/1830704523@3c01d268, $$Lambda$1150/1830704523@26415f0b)

When you get any value from x and pass any value to it. It will concatenate that value with v1.

scala> x.head(1)
res16: String = a1

scala> x.last(5)
res17: String = b5

scala> x.last("a")
res18: String = ba

scala> x.last(5.0f)
res19: String = b5.0

But in the first version, it takes only values of l2 because they have been concatenated explicitly. That's why both differ.

Upvotes: 3

Alexey Romanov
Alexey Romanov

Reputation: 170859

The equivalent to b => "" + v1 + b using underscores is just "" + v1 + _.

_ => "" + v1 + _ is instead equivalent to _ => (b => "" + v1 + b) or a => (b => "" + v1 + b).

Upvotes: 5

Related Questions