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

0__*_*0__ 6 scala implicit type-parameter

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

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

这有效:

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

而这不是:

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

随着消息"inferred type arguments [Repr] do not conform to method apply's type parameter bounds [Repr <: State[Repr]]".由于证据ev表明这种构象,我想知道如何StateY解决.

Mil*_*bin 6

你的问题是,即使表单的证据A <:< B暗示类型的值A可以转换为类型的值,B但它并不意味着A <: B...实际上,使用类型约束或视图绑定而不是普通的主要原因类型绑定正是因为这种子类型关系不成立.

因此在约束StateY,Repr <:< State[Repr]是不足以满足结合Repr <: State[Repr]Observerapply方法.假设您想要放宽对StateX类型参数的约束,您唯一的选择是相应地削弱apply方法类型参数的约束.使用视图绑定而不是普通类型绑定,可以获得类似下面的内容,

object Observer {
  def apply[Repr <% State[Repr]](reader : Reader[Repr]) : Observer[Repr] =
    new Observer[Repr] {}
}
Run Code Online (Sandbox Code Playgroud)

或者,

object Observer {
  def apply[Repr](reader : Reader[Repr])
                 (implicit ev : Repr <:< State[Repr]) : Observer[Repr] =
    new Observer[Repr] {}
}
Run Code Online (Sandbox Code Playgroud)

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


Did*_*ont 5

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

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