12
votes

When defining a case class, the default companion object has nice curried method to get a curried version of the case class constructor:

scala> case class Foo(a: String, b: Int)
defined class Foo

scala> Foo.curried
res4: String => (Int => Foo) = <function1>

However, as soon as I define an explicit companion object, this method disappears:

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Foo(a: String, b: Int)
object Foo {}

// Exiting paste mode, now interpreting.

defined class Foo
defined module Foo

scala> Foo.curried
<console>:9: error: value curried is not a member of object Foo
              Foo.curried

I can get it back like so:

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Foo(a: String, b: Int)
object Foo { def curried = (Foo.apply _).curried }

// Exiting paste mode, now interpreting.

defined class Foo
defined module Foo

scala> Foo.curried
res5: String => (Int => Foo) = <function1>

However, I'd like to know why it disappears when defining an explicit companion (eg. in contrast to apply)?

(Scala 2.9.2)

1
Maybe the synthetic companion extends Function2 and gets curried from there? Then perhaps you could do it as well.Michał Politowski
Don't know why it's missing, but as a workaround (Foo(_,_)).curried has the same effectLuigi Plinge
There's a related question here—not exactly a duplicate, so I won't flag as such—with a fairly authoritative accepted answer.Travis Brown
@MichałPolitowski Indeed, explicitly extending Function2 does the trick.romanb
@TravisBrown Thanks for the link, missed that one.romanb

1 Answers

2
votes

Scalac create a default companion for each case class. The default companion implements scala.Functionn.

When you define an explicit companion, Scalac will merge the explicit companion with default one.

If you want to invoke curried, you must let your explicit companion implements Function2. Try:

case class Foo(a: String, b: Int)
object Foo extends ((String, Int) => Foo) {
  def otherMethod = "foo"
}