Curried case class constructor on companion
Asked Answered
R

1

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)

Rapids answered 20/10, 2012 at 13:25 Comment(7)
Maybe the synthetic companion extends Function2 and gets curried from there? Then perhaps you could do it as well.Tamah
Don't know why it's missing, but as a workaround (Foo(_,_)).curried has the same effectSuboceanic
There's a related question here—not exactly a duplicate, so I won't flag as such—with a fairly authoritative accepted answer.Fragrant
@MichałPolitowski Indeed, explicitly extending Function2 does the trick.Rapids
@TravisBrown Thanks for the link, missed that one.Rapids
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.Acrilan
You can also get to the apply method explicitly, instead of through the Foo() sugar. So, (Foo.apply _).curried gets it.Maccaboy
H
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"
}
Hiedihiemal answered 23/11, 2012 at 18:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.