Это отлично работает:
def echo[A, B](a: A, b: B): A = ???
Это тоже нормально:
def echo[A, B](a: A, b: B): B = ???
Однако как нам добиться этого, чтобы вернуть либо тип A, либо тип B?
// error def echo[A, B](a: A, b: B): A|B = ???
Возможно ли просто иметь тип объединения из универсальных типов A и B? Ваше здоровье.
ОБНОВЛЕНИЕ1
Either
— вариант, но не идеальный, так как при обработке возвращаемого результата требуется совпадение с шаблоном. По сути, я хочу этого: A <: A|B
, B <: A|B
, чего Either
не достигает.
Другая крайность, я могу сделать это, но шрифт слишком свободный:
def echo[A, B](a: A, b: B): Any = ???
ОБНОВЛЕНИЕ 2
Почему мне не нужен Either
?
(Причина 2)
Возвращаемый результат на самом деле будет Dataset
Spark, что требует Encoder
для любого типа, который не является подтипом Product
(см. эту тему).
При многократном вызове этого метода он приводит к слишком большому количеству Either
, обертывающих друг друга, например. Either[Either[Either[...]]]
. Для этого требуется определить слишком много кодировщиков.
Итак, я на самом деле делаю это:
def echo[A, B](a: A, b: B): Dataset[A|B] = ???
Если я сделаю это, потребуется много разных кодировщиков из-за типа Either
:
def echo[A, B](a: A, b: B): Dataset[Either[A, B]] = ???
val result1: Either[Cat, Dog] = echo(a: Cat, b: Dog)
val result2: Either[Either[Cat, Dog], Pig] = echo(result1: Either[Cat, Dog], c: Pig)
// we have to define encoders:
implicit encoder1: org.apache.spark.sql.Encoders.kryo[Either[Cat, Dog]]
implicit encoder2: org.apache.spark.sql.Encoders.kryo[Either[Either[Cat, Dog], Pig]]
// if we keep iterating, then too many encoders to define...
@specialized
работает только для определенных типов, то есть он не может выполнятьdef echo[@specialized(A,B) AB](a: A, b: B, ab: AB) = ???
(гдеA
иB
— общие типы). Во-вторых, кажется, что он не может вернуть тип@specialized
, например.def echo[A, B](a: A, b: B): @specialized(A,B) = ???
Обе ошибки! - person jack   schedule 08.03.2021Either
неплохо, но требует сопоставления с образцом при обработке возвращаемого результата. По сути, я хочу этого:A <: A|B
,B <: A|B
, чегоEither
не достигает. - person jack   schedule 08.03.2021print
илиequals
, но для этого вы могли бы просто используйтеAny
). - person Dima   schedule 08.03.2021