Объединить классы без перечисления аргументов - PullRequest
0 голосов
/ 16 марта 2020

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

case class A(a: Int)
case class B(b: Double)
case class C(a: Int, b: Double) {
  def this(a: A, b: B) = this(a.a, b.b)
}

val a = A(1)
val b = B(1.0)
val c: C = C(a, b)

Проблема с этим заключается в том, что это включает в себя запись каждого отдельного аргумента в строке this(a.a, b.b), и если ваши классы case принимают большое количество аргументов Это нудно и неуместно. Что я хочу сделать, так это как-то «разделить» классы падежей на больший класс, написав что-то вроде this(a _:*, b _:*) или что-то подобное, чтобы мне не пришлось выписывать все аргументы. Как бы я совершил sh это?

1 Ответ

1 голос
/ 16 марта 2020

Если вы хотите сделать это для фиксированных классов A, B и C, это довольно просто с библиотекой shapeless . Просто конвертируйте A и B в HList s, добавляйте эти списки и конвертируйте результат обратно в C:

import shapeless.Generic
import shapeless.syntax.std.tuple._
import shapeless.syntax.std.product._

object C {
  def apply(a: A, b: B): C = 
    Generic[C].from(a.toHList ++ b.toHList)
}

Вы можете сделать это более обобщенным образом c , Например, вы можете использовать не только фиксированные классы A и B, но и любые 2 класса или кортежа, которые могут быть добавлены для точного соответствия форме C. Код для этого, в основном, просит shapeless неявно предоставить все необходимые операции (преобразования из и в классы case в HList s и добавление HList s), а затем выполняет эти операции:

import shapeless.ops.hlist.Prepend
import shapeless.{Generic, HList}

object C {
  def apply[A, B, HA <: HList, HB <: HList, HC <: HList](a: A, b: B)(implicit
    genA: Generic.Aux[A, HA],
    genB: Generic.Aux[B, HB],
    genC: Generic.Aux[C, HC],
    prepend: Prepend.Aux[HA, HB, HC],
  ): C = genC.from(prepend(genA.to(a), genB.to(b)))
}

Обратите внимание, что во всех случаях подход shapeless требует затрат времени выполнения, что может быть нежелательно для чего-то такого простого, как добавление двух классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...