Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do case classes extend only Product and not Product1, Product2, ..., ProductN?

after I learned that case classes extend Product, I wondered why they do not extend ProductN. E.g., given a code like:

case class Foo(a: Int)

I'd expect Foo(1).asInstanceOf[Product1[Int]] to work, but it does not (checked with Scala 2.9.1, and confirmed by other sources and by Product documentation).

I was interested in this, because I wanted to declare classes such as:

abstract class UnaryOp[T1 <: Exp[_], R](t1: T1) extends Exp[R] {
  this: Product1[T1] =>
}

This way, a node for a Unary operation must be implement Product1. It would be nice if being simply a case class with one parameter would be enough for this.

like image 550
Blaisorblade Avatar asked Sep 07 '11 18:09

Blaisorblade


People also ask

Can Case classes extend?

A class can extend another class, whereas a case class can not extend another case class (because it would not be possible to correctly implement their equality).

What is the difference between Case class and normal class?

The case class is defined in a single statement with parameters (syntax for defining case class) whereas the normal class is defined by defining method and fields (syntax for defining class). While creating objects of case class, new keyword is not used which is used to create instances of case class.

Why do we need case class in Scala?

A Scala Case Class is like a regular class, except it is good for modeling immutable data. It also serves useful in pattern matching, such a class has a default apply() method which handles object construction. A scala case class also has all vals, which means they are immutable.

Are Case classes serializable?

The main differences are that case objects are serializable and have a default hashCode implementation as well as a toString implementation. Case objects are useful for enumerations and creating containers for messages.


2 Answers

Consider this:

case class X(n: Int)
case class Y(x: String, y: Int) extends X(y)

If case classes extended ProductN, then that would extend both Product1 and Product2, but the type parameter changes, so there are two different overloads for _1. This is just one problem -- I bet there are others.

Now, case class inheriting case class has been deprecated, and Martin Odersky is now considering making them inherit ProductN. AFAIK, is has not been done yet, but the obstacle has been removed.

like image 124
Daniel C. Sobral Avatar answered Oct 21 '22 07:10

Daniel C. Sobral


I brought it back shortly after martin said we could do it. It doesn't work right yet, but to the extent that it does, it's behind -Xexperimental in trunk builds.

scala> case class Foo[T, U](x1: T, x2: U)
defined class Foo

scala> Foo(List("a"), "b")
res0: Foo[List[java.lang.String],java.lang.String] = Foo(List(a),b)

scala> res0.isInstanceOf[Product2[_,_]]
res1: Boolean = true
like image 31
psp Avatar answered Oct 21 '22 07:10

psp