12

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)

romanb
  • 6,391
  • 2
  • 20
  • 19
  • 1
    Maybe the synthetic companion extends Function2 and gets curried from there? Then perhaps you could do it as well. – Michał Politowski Oct 20 '12 at 14:28
  • Don't know why it's missing, but as a workaround `(Foo(_,_)).curried` has the same effect – Luigi Plinge Oct 20 '12 at 14:41
  • 3
    There's a related question [here](http://stackoverflow.com/q/3049368/334519)—not exactly a duplicate, so I won't flag as such—with a fairly authoritative accepted answer. – Travis Brown Oct 20 '12 at 14:44
  • @MichałPolitowski Indeed, explicitly extending Function2 does the trick. – romanb Oct 20 '12 at 14:50
  • @TravisBrown Thanks for the link, missed that one. – romanb Oct 20 '12 at 14:51
  • So, as I understand from @Martin Odersky answer, it was made for backwards compatibility, am I right? I also checked, `Scala 2.10.0-M7` behaves the same. – 4e6 Oct 20 '12 at 14:51
  • You can also get to the apply method explicitly, instead of through the Foo() sugar. So, `(Foo.apply _).curried` gets it. – brandon Nov 20 '12 at 19:53

1 Answers1

2

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"
}
Yang Bo
  • 3,586
  • 3
  • 22
  • 35