将抽象类型的(隐式)值注入到特征

时间:2016-02-16 21:06:33

标签: scala types traits type-parameter path-dependent-type

这是我的方案的简化,我试图让它工作

// the UnrelatedN are mostly used as tag traits, for type-checking purposes
trait Unrelated1
trait Unrelated2

trait HasUnrelatedSupertrait {
  type Unrelated  // abstract type
}

trait HasUnrelated[... /*TODO: Parametrize with (factory of) UnrelatedN*/]
    extends HasUnrelatedSupertrait {
  type Unrelated = UnrelatedType  // path-dependent type
  implicit val unrelated = ... // instantiate or access (singleton) instance of Unrelated
}

trait Subtype1 extends HasUnrelated[/* Something involving Unrelated1 */] with ...
trait Subtype2 extends HasUnrelated[/* Something involving Unrelated2 */] with ...
// ... (many more similar subtypes)

基本上,我想注入隐式val实例 在非侵入式中抽象类型到({1}}的(子类型) 希望通过一个类型参数,我有一些灵活性 结束(见TODO)。

(我不在乎是否通过new构建了Unrelated1 / 2实例, 工厂以及如何定义这些工厂(作为对象,类 等),只要我能得到2个不同的Unrelated1 / 2实例。)

我的尝试失败的一些限制因素是:

  • HasUnrelatedHasUnrelated必须是特征,而不是类
  • traits不能有参数(所以我不能传递(隐式)val工厂)
  • traits不能有上下文或视图边界(引入ClassTag / TypeTag)
  • 我不愿意混淆HasUnrelatedSupertrait的所有子类型 附加类型/ val声明

但是,我愿意做以下一项或多项修改:

  • 为Unrelated1 / 2
  • 介绍(单身)工厂
  • 在Unrelated1 / 2中引入任意继承,只要这些继承 类型仍然不相关(也不是另一个的子类型)
  • 只要需要额外费用,就可以将超类型添加到HasUnrelated HasUnrelated中的声明(如果有) ,但不包含任何子类型

有没有办法在Scala中实现这一点,如果是这样的话?

1 个答案:

答案 0 :(得分:0)

你可能正在寻找类型课吗?考虑这个例子

trait Companion[T] {
  val comp: T
}

object Companion {
  def apply[T: Companion] = implicitly[Companion[T]]
}

object UnrelatedType {
  implicit val thisComp = 
    new Companion[UnrelatedType.type] { 
      val comp = UnrelatedType 
    }
}

// Somewhere later
type Unrelated = UnrelatedType
implicit val unrelated = Companion[UnrelatedType]