改进特征的丑陋参数列表

Improving ugly parameter list on traits

我正在研究的问题涉及定义一个具有类型参数的特征,其中它的类型参数具有类型参数,我也需要知道这些类型。例如,考虑以下代码:

trait JoinData[A <: Attributes,
               L <: Entity[A], 
               B <: Keyed
               R <: Document[B],
               O <: Output[A, B]] extends Something[A,L,B,R]{

  def method1(a:A) : String
  def method2(L, R) : O = {
     ...
  } 
  ...
}

当用户实现此功能时,类型 L 和 R 确实决定了 A 和 B 必须是什么,但是我不确定是否可以从我的 API 中删除 A 和 B。

这个问题导致 APIs 非常丑陋,用户很难理解为什么他们必须指定某些类型,甚至他们应该是什么。

任何人都可以指出我如何解决这个问题的一些想法(如果可能的话!)。

如果没有关于您的 API 及其使用方式的任何详细信息,很难回答您的问题。目前还不清楚为什么单态

trait JoinData extends Something {
  def method1(a: Attributes): String
  def method2(e: Entity, r: Document): Output = {
     ...
  } 
  ...
}

不够。

您可以尝试用类型成员替换(部分)类型参数:

trait Attributes
trait Entity {
  type A <: Attributes
}
trait Keyed
trait Document {
  type B <: Keyed
}
trait Something[L <: Entity, R <: Document]
trait Output[A <: Attributes, B <: Keyed]
trait JoinData[L <: Entity, R <: Document] extends Something[L, R]{
  def method1(a: L#A): String
  def method2(l: L, r: R): Output[L#A, R#B] = ???
}

使用类型投影或

trait Attributes
trait Entity
trait Keyed
trait Document
trait Something[L <: Entity, R <: Document]
trait Output[A <: Attributes, B <: Keyed]
trait TC[L <: Entity] {
  type A <: Attributes
}
trait TC1[R <: Document] {
  type B <: Keyed
}

abstract class JoinData[L <: Entity, R <: Document](implicit val tc: TC[L]) extends Something[L, R]{
  def method1(a: tc.A) : String
  def method2(l: L, r: R)(implicit tc1: TC1[R]): Output[tc.A, tc1.B] = ???
}

使用类型 类。