When having a case class with a type parameter, I don't see how I can call the tupled
method. It seems to be find with apply
and unapply
.
scala> case class Foo[T](x:T, y:T)
defined class Foo
scala> Foo.apply[Int] _
res1: (Int, Int) => Foo[Int] = <function2>
scala> Foo.unapply[Int] _
res2: Foo[Int] => Option[(Int, Int)] = <function1>
scala> Foo.tupled[Int] _
<console>:10: error: value tupled is not a member of object Foo
Foo.tupled[Int] _
^
Any idea on what's going on?
Companion objects of case classes cannot extend FunctionN
(which defines tupled
, with N
>= 2) when they have type parameters. Use
(Foo[Int] _).tupled
When you have a vanilla class such as
case class Bar(x: Int, y: Int)
its constructor is effectively a Function2[Int, Int, Bar]
, hence when the compiler generates the companion object Bar
it can conveniently make it extend Function2
.
The generated code will then be
class Bar extends AnyRef with Product with Serializable { ... }
object Bar extends Function2[Int, Int, Bar] with Serializable { ... }
Now consider
case class Foo[T](x: T, y: T)
If you try to apply the same trick, you'll find yourself in trouble very soon:
// this can't compile, what's T?
object Foo extends Function2[T, T, Bar] with Serializable { ... }
Since T
is unknown, the compiler can't make Foo
a subclass of Function2
and it can't do much better than make it extend AnyRef
:
class Foo[T] extends AnyRef with Product with Serializable { ... }
object Foo extends AnyRef with Serializable { ... }
Here's a quick proof of what discussed above (using scala -Xprint:typer
):
scala> case class Bar(x: Int, y: Int)
...
<synthetic> object Bar extends scala.runtime.AbstractFunction2[Int,Int,Bar] with Serializable {
...
scala> case class Foo[T](x: T, y: T)
...
<synthetic> object Foo extends AnyRef with Serializable {
...
To wrap it up, when you have type parameters, you have to obtain a Function2
first
val f: Function2[Int, Int, Foo] = Foo[Int] _
and then you can call tupled
on it
f.tupled // ((Int, Int)) => Foo[Int]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With