“播放源文件”;读.scala“;广义类型约束的使用

“播放源文件”;读.scala“;广义类型约束的使用,scala,playframework,playframework-2.0,playframework-2.1,Scala,Playframework,Playframework 2.0,Playframework 2.1,在Play framework源文件中,trait Reads[A]中有以下方法: def andThen[B](rb: Reads[B])(implicit witness: A <:< JsValue): Reads[B] = rb.compose(this.map(witness)) 证人属于A类B 有人能解释一下吗?谢谢 这是因为此类型的见证也是一个函数。声明如下: 最后一个方法makeBip2在没有隐式表达式的情况下无法编译,因为尽管有证据表明a是根,但类型系统不

在Play framework源文件中,trait Reads[A]中有以下方法:

def andThen[B](rb: Reads[B])(implicit witness: A <:< JsValue): Reads[B] =
    rb.compose(this.map(witness))
证人属于A类B


有人能解释一下吗?谢谢

这是因为此类型的见证也是一个函数。声明如下:

最后一个方法
makeBip2
在没有隐式表达式的情况下无法编译,因为尽管有证据表明
a
,但类型系统不会。你可以投下它,它肯定会起作用:

def makeBip3[A](a: A)(implicit ev: A <:< Root) {
  a.asInstanceOf[Root].bip() // ugly
}
由于隐式参数在方法中作为隐式参数提供,
a.bip()
将自动转换为
ev(a).bip()
,您不需要知道涉及到函数

但是,类型系统仅使用隐式将
A
解析为
JsValue
,而不是将
Seq[A]
解析为
Seq[JsValue]
或将
Reads[A]
解析为
Reads[JsValue]

因此,在您的例子中,
this.map(witness)
只是让类型系统理解a
读取[a]
是a
读取[JsValue]
,方法是应用不做任何事情的函数,这样它就可以由接受
JsValue
并返回a
B
的内容组成


有关更多信息,请参见SO上的问题。

这是因为此类型见证也是一个函数。声明如下:

最后一个方法
makeBip2
在没有隐式表达式的情况下无法编译,因为尽管有证据表明
a
,但类型系统不会。你可以投下它,它肯定会起作用:

def makeBip3[A](a: A)(implicit ev: A <:< Root) {
  a.asInstanceOf[Root].bip() // ugly
}
由于隐式参数在方法中作为隐式参数提供,
a.bip()
将自动转换为
ev(a).bip()
,您不需要知道涉及到函数

但是,类型系统仅使用隐式将
A
解析为
JsValue
,而不是将
Seq[A]
解析为
Seq[JsValue]
或将
Reads[A]
解析为
Reads[JsValue]

因此,在您的例子中,
this.map(witness)
只是让类型系统理解a
读取[a]
是a
读取[JsValue]
,方法是应用不做任何事情的函数,这样它就可以由接受
JsValue
并返回a
B
的内容组成

有关更多信息,请参见上面的问题

sealed trait Root { def bip() { println("bip") } }

def makeBip[A <: Root](a: A) {
  a.bip() // works because a is known to the type system to be a Root
}

def makeBip2[A](a: A)(implicit ev: A <:< Root) {
  a.bip() // works, because implicit resolution turns it into `ev(a).bip()`
}
def makeBip3[A](a: A)(implicit ev: A <:< Root) {
  a.asInstanceOf[Root].bip() // ugly
}
def makeBip4[A](a: A)(implicit ev: A <:< Root) {
  ev(a).bip() // works!
}