3

Possible Duplicate:
Underscore in List.filter

This works (as intended):

List(true, false, true).filter(_ == true).foreach(println)

but I can't write it this way:

List(true, false, true).filter(_).foreach(println)

Why?

Community
  • 1
  • 1
John Difool
  • 5,572
  • 5
  • 45
  • 80

2 Answers2

9

@sshaef is right, this is a duplicate. The linked answer is really verbose though, so here's a simple answer:

You expect list.filter(_) to expand to something like list.filter(x=>x), but instead the Scala compiler treats it the same as list.filter _, which is completely different. The result is a partially-applied filter on your list instead of filtering your list with the identity function. This is obvious when you try it in the REPL:

scala> List(true, false, true).filter(_)
res0: (Boolean => Boolean) => List[Boolean] = <function1>

scala> List(true, false, true).filter _
res1: (Boolean => Boolean) => List[Boolean] = <function1>

scala> List(true, false, true).filter(x=>x)
res2: List[Boolean] = List(true, true)

scala> List(true, false, true).filter(identity)
res3: List[Boolean] = List(true, true)

scala> List(true, false, true).filterNot(!_)
res4: List[Boolean] = List(true, true)

Notice how the last case works because we include the ! operator in front of _, so it knows you're using it as an anonymous argument rather than using it to partially apply the function.

DaoWen
  • 32,589
  • 6
  • 74
  • 101
2

Just for another angle, depending on what your goal is, this is just as short and concise:

for(a <- List(true, false, true) if a) println(a)
thoredge
  • 12,237
  • 1
  • 40
  • 55