交换证据参数的类型参数的上限

时间:2012-01-02 15:41:58

标签: scala implicit type-parameter

我想放宽对trait类型参数的约束,而是将它们以证据参数的形式强加给方法。鉴于一些骨架设置:

trait State[Repr]
object Observer {
  def apply[Repr <: State[Repr]](reader: Reader[Repr]): Observer[Repr] = 
    new Observer[Repr] {}
}
trait Observer[A]
trait Reader  [A]

这有效:

trait StateX[Repr <: StateX[Repr]] extends State[Repr] { 
  protected def reader: Reader[Repr]
  def observe: Observer[Repr] = Observer(reader)
}

这不是:

trait StateY[Repr] extends State[Repr] { 
  protected def reader: Reader[Repr]
  def observe(implicit ev: Repr <:< State[Repr]): Observer[Repr] = Observer(reader)
}

留言"inferred type arguments [Repr] do not conform to method apply's type parameter bounds [Repr <: State[Repr]]"。由于证据ev表明了这种构象,我想知道如何修复StateY

2 个答案:

答案 0 :(得分:6)

您的问题是,即使A <:< B形式的证据暗示类型A的值可以转换为类型B的值,也不意味着{{1}实际上,使用类型约束或视图绑定而不是普通类型绑定的主要原因恰恰是因为这种子类型关系不成立。

因此,A <: BStateY中的约束不足以满足Repr <:< State[Repr] Repr <: State[Repr]方法上的绑定Observer。鉴于您想要放宽对apply类型参数的约束,您唯一的选择是相应地削弱对StateX方法的类型参数的约束。这可以使用视图绑定而不是普通类型绑定来获得类似下面的内容,

apply

或者,

object Observer {
  def apply[Repr <% State[Repr]](reader : Reader[Repr]) : Observer[Repr] =
    new Observer[Repr] {}
}

如果你宁愿在整个过程中使用约束。

答案 1 :(得分:5)

证据表明Repr可以转换为State[Repr]。它没有说明使用Reader [Repr]可以做些什么。

在给定A =&gt;的情况下,没有将T [A]转换为T [B]的通用方法(独立于T)。 B.对于协变T可能是可能的,但语言中没有这样的东西。