【问题标题】:Is it possible to create a generic type T[A <: C[U], B <: C[U], U] that can be used as T[A, B]?是否可以创建一个可以用作 T[A, B] 的泛型类型 T[A <: C[U], B <: C[U], U]?
【发布时间】:2015-06-02 18:12:32
【问题描述】:

我有以下案例类:

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

我想这样使用它:

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

但是,我收到一条错误消息,指出 &lt;*&gt; 需要三个参数,而我只给出了两个。我希望它像这样工作:

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) 非法继承;
自类型&lt;*&gt;[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]
  ^

有解决办法吗?如有必要,我不介意重命名案例类,尽管我确实想要漂亮的中缀语法。

【问题讨论】:

  • @Kigyo 它不会编译。类型 T 仍然未知
  • @wedens 你是对的。我一定在 repl 中输入了不同的内容。谢谢。
  • 我知道这是一个老问题,但不是第一个 Quantity[_] 和第二个被视为不同类型的问题(在“不同范围内使用相同的占位符名称 _$1 “)?我想我曾经有过这样的经历。

标签: scala generics


【解决方案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])

然后&lt;*&gt; 是所需的双参数类型,但您只能用适当相关的QR 实例化Q &lt;*&gt; R(因为隐式CanStar[Q, R]s 仅适用于合适的@ 987654328@ 和 R)。

【讨论】:

  • 问题是value必须是T类型,而不是Q类型。
  • 在这种情况下value: Anycs: CanStar[Q, R, value.type] ?
猜你喜欢
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
相关资源
最近更新 更多