如何将特征的类型参数限制在一组不同的类型中(例如,以联合类型为约束)?
作为一个具体的例子,我想创建一个特征IntegralIndex[T]
,其中T
必须Int
或Long
。
我尝试了this question on union types的第一个答案:
sealed abstract class NumericIndex[T]
object NumericIndex {
implicit object IntWitness extends NumericIndex[Int]
implicit object LongWitness extends NumericIndex[Long]
}
trait IntegralIndex[T : NumericIndex]
但这不起作用;我得到traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'
还有其他建议吗?诚然,我不理解关于工会类型问题的其他解决方案,所以如果答案只是在那里使用不同的答案,或者甚至知道无法完成,我会很感激。
答案 0 :(得分:6)
类型类方法可能是在这里完成您想要的最简洁的方法,并且您的版本正确。它不能以当前形式工作,因为上下文边界只是隐式参数的语法糖。以下特征定义,例如:
trait IntegralIndex[T: NumericIndex]
会对这样的事情感到害怕:
trait IntegralIndex[T](implicit num: NumericIndex[T])
但是traits没有构造函数,所以这不是有效的Scala语法。但是,你可以这样写:
trait IntegralIndex[T] {
implicit def num: NumericIndex[T]
}
这确保您无法创建IntegralIndex[T]
,除非您有证据表明NumericIndex
的{{1}}类型类的实例。
现在,当您实施T
时,您可以写下:
IntegralIndex
或者:
case class MyIndex[T](whatever: String)(implicit val num: NumericIndex[T])
现在,使用case class MyIndex[T: NumericIndex](whatever: String) {
implicit val num = implicitly[NumericIndex[T]]
}
的任何人都无法看到所有隐式管道。