Take the 2-minute tour ×

Having two simple classes taking Int as an argument:

case class Foo(i: Int)
     class Bar(j: Int)

I can say:

List(1,2,3) map Foo

Which works fine and is equivalent to a bit more verbose:

List(1,2,3) map {Foo(_)}

However Bar (because it is not a case class?) cannot be used in the same construct:

List(1,2,3) map Bar

  error: not found: value Bar
          List(1,2,3) map Bar

Is there some special syntax to reference any constructor and take advantage of eta expansion? List(1,2,3) map {new Bar(_)} seems a bit more verbose compared to Foo.

share|improve this question
Eta expansion is something that happen to methods. Note that a constructor is not a method. –  Daniel C. Sobral Oct 8 '11 at 13:56
add comment

2 Answers

up vote 11 down vote accepted

It works in the former case, because companion object of a case class extends appropriate FunctionN trait. (object Foo extends (Int => Foo) in your example.) For non-case classes, you could do this manually:

scala> class Bar(i: Int)
defined class Bar

scala> class Bar(i: Int); object Bar extends (Int => Bar) { def apply(i: Int) = new Bar(i) }
defined class Bar
defined module Bar

scala> List(2, 3) map Bar
res17: List[Bar] = List(Bar@1f99e90, Bar@1191056)

IMO it's better to go with new Bar(_) as this extra boilerplate might not be worth the little concision achieved.

share|improve this answer
Interesting, wasn't aware that a case class extends FunctionN. I remember a SO answer where all automatic features of case classes are listed but don't remember that issue mentioned. –  Peter Schmitz Oct 8 '11 at 16:38
case classes don't. Their companion objects do. –  missingfaktor Oct 8 '11 at 17:19
ohh sorry, of course, mixed that up. –  Peter Schmitz Oct 9 '11 at 10:16
add comment

Since Foo is a case class there is also a companion object called Foo, which implements the Function1 interface (had the constructor taken three arguments it would have been the Function3 interface).

share|improve this answer
add comment

Your Answer


