Почему классы вариантов расширяют только 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] =>
}

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


person Blaisorblade    schedule 07.09.2011    source источник
comment
Меня смущает голос против. Может ли противник объяснить?   -  person Blaisorblade    schedule 23.02.2013


Ответы (3)


Учти это:

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

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

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

person Daniel C. Sobral    schedule 08.09.2011
comment
Да, надеюсь, это войдет в будущую версию Scala, поскольку она позволяет писать типобезопасные универсальные функции декомпозиции для классов case. - person Jesper Nordenberg; 08.09.2011
comment
Можно ли наследовать case-классы в Scala? - person Taky; 22.02.2016
comment
Учитывая, насколько Scala изменилась с тех пор, как вы предоставили этот ответ, в частности наследование класса case, которое вы описали выше, устарело в моих версиях Scala назад (задолго до 2.12 ... текущей версии), вопрос теперь снова открыт. Есть ли шанс, что он наконец-то будет добавлен в линейку Scala 2.x? Есть ли шанс, что это было исправлено для Scala 3 (Dotty), и если да, то будет ли оно перенесено на линию 2.x? - person chaotic3quilibrium; 27.05.2019

Я вернул его вскоре после того, как Мартин сказал, что мы можем это сделать. Это пока не работает должным образом, но в той степени, в которой это работает, оно отстает от -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
person psp    schedule 08.09.2011
comment
Спасибо, это здорово - было бы хорошо, если бы это было для следующего выпуска Scala! Я не был уверен, какой ответ принять, но, в конце концов, я думаю, что мне все же придется согласиться с ответом Дэниела С. Собрала за предоставление объяснения. - person Blaisorblade; 09.09.2011
comment
Я пробовал это в 2.10.0-M5, но результаты были запутанными. _1 и _2 присутствуют в Foo, но это не подтип Product2, и эти члены не задокументированы в Scaladoc: scala> Foo(List("a"), "b") res10: Foo[List[String],String] = Foo(List(a),b) scala> res10.isInstanceOf[Product2[_,_]] res11: Boolean = false scala> res10._1 res12: List[String] = List(a) scala> Some(1)._1 res13: Int = 1 - person Blaisorblade; 20.07.2012
comment
Что с этим случилось, учитывая, что класс дела, унаследованный от другого класса, устарел? Есть ли возможность его появления в текущих версиях 2.x и / или в Scala 3 (Dotty)? - person chaotic3quilibrium; 27.05.2019

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

person agilesteel    schedule 07.09.2011
comment
Добавление val _1: Int приведет к потере памяти в каждом экземпляре, но Product1[T] имеет абстрактное определение def _1: T, и добавление реализации для этого (def _1: T = a) не меняет размер экземпляра. См. Ответ Дэниела С. Собрала! - person Blaisorblade; 09.09.2011
comment
Что бы здесь случилось? case class C (_2: String, _1: Int) - person nafg; 13.11.2012