是否可以创建可以用作T [A,B]的泛型类型T [A<:C [U],B&lt ;: C [U],U]?

时间:2014-07-12 21:40:08

标签: scala generics

我有以下案例类:

case class <*>[Q <: Quantity[T], R <: Quantity[T], T](value: T) 
  extends Quantity[T]

我想这样使用它:

type Area[T] = Length[T] <*> Length[T]

但是,我得到一个错误,说<*>需要三个参数而我只给了两个参数。我希望它能像这样工作:

type Area[T] = <*>[Length[T], Length[T], T]

我尝试了以下但是它给了我一个错误:

trait Quantity[T] {
  type Value = T

  def value: T
}

case class <*>[Q <: Quantity[_],
               R <: Quantity[_]](value: Q#Value)
                                (implicit eq: Q#Value =:= R#Value)
  extends Quantity[Q#Value]
  

错误:(13,110)非法继承;
  自我类型<*>[Q,R]不符合Quantity[_$1]的自我类型Quantity[_$1]

case class <*>[Q <: Quantity[_],
               R <: Quantity[_]](value: Q#Value)
                                (implicit eq: Q#Value =:= R#Value)
  extends Quantity[Q#Value]
  ^

有解决方法吗?我不介意在必要时重命名案例类,虽然我确实需要漂亮的中缀语法。

1 个答案:

答案 0 :(得分:1)

问题是Q#Value引用。

我建议使用隐式来强制执行您的类型约束,而不是尝试使存在感有效:

sealed trait CanStar[Q, R]
// could include =:=-like values in CanStar if you like
object CanStar {
  implicit def canStar[Q <: Quantity[T], R <: Quantity[T], T] =
    new CanStar[Q, R]{}
}

sealed case class <*>[Q,R](value: Q)(implicit cs: CanStar[Q, R])

然后<*>是所需的双参数类型,但您只能使用Q <*> RQ实例化R,这些CanStar[Q, R]Q具有适当的相关性(因为隐式{{ 1}}仅适用于合适的RcomponentWillUnmount)。