Подтвердить что ты не робот

Почему классы case расширяют только Product, а не Product1, Product2,..., ProductN?

после того, как я узнал, что классы case расширяют Product, я задавался вопросом, почему они не распространяют ProductN. Например, с учетом кода типа:

case class Foo(a: Int)

Я ожидаю, что Foo(1).asInstanceOf[Product1[Int]] будет работать, но это не так (отмечено с помощью Scala 2.9.1 и подтверждено другими источниками и документацией Product).

Мне это было интересно, потому что я хотел объявить классы, например:

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

Таким образом, node для унарной операции должен быть реализован Product1. Было бы неплохо, если бы для этого было просто класс case с одним параметром.

4b9b3361

Ответ 1

Рассмотрим это:

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

Если классы case расширены ProductN, то это расширит как Product1, так и Product2, но параметр типа изменится, поэтому для _1 существуют две разные перегрузки. Это всего лишь одна проблема - я уверен, что есть и другие.

Теперь класс case, наследующий класс case, устарел, и Мартин Одерски теперь рассматривает возможность наследования ProductN. AFAIK, еще не сделано, но препятствие было устранено.

Ответ 2

Я вернул его вскоре после того, как Мартин сказал, что мы можем это сделать. Пока это не работает, но в той степени, в которой это происходит, оно находится за -Xexperimental в строках сборки.

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

Ответ 3

Если бы Product1[Int] было автоматически расширено, то также необходимо было бы указать val _1: Int. Хотя я мог себе представить, что он может быть автоматизирован, что a получает привязку к _1 и т.д. И т.д., Но это не так. Наверное, просто не усложнять ситуацию.