[英]What is the implicit resolution sequence in this “simple” ScalaZ tutorial code example?
The code snippet below is taken from this ScalaZ tutorial. 下面的代码片段取自此 ScalaZ教程。
I cannot figure out how the implicit resolution rules are applied when evaluating 10.truthy
at the bottom of the code example. 在评估代码示例底部的10.truthy
时,我无法弄清楚隐式解析规则是如何应用的。
Things that - I think - I do understand are the following: 我认为 - 我明白的事情如下:
1) The implicit value intCanTruthy
is an instance of an anonymous subclass of CanTruthy[A]
which defines the truthys
method for Int
-s according to : 1)隐含值intCanTruthy
是CanTruthy[A]
的匿名子类的实例,它CanTruthy[A]
内容定义Int
-s的truthys
方法:
scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({
case 0 => false
case _ => true
})
intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1@71780051
2) The toCanIsTruthyOps
implicit conversion method is in scope when evaluating 10.truthy
, so the compiler will try to use this implicit conversion method when it sees that Int
does not have a truthy
method. 2)当评估10.truthy
, toCanIsTruthyOps
隐式转换方法在范围内,因此当编译器看到Int
没有truthy
方法时,它将尝试使用这种隐式转换方法。 So the compiler will try to look for some implicit conversion method which converts 10
into an object that does have a truthy
method and therefor it will try toCanIsTruthyOps
to this conversion that. 所以编译器会尝试寻找它转换一些隐式转换方法10
进入的对象不具有truthy
方法及其它会尝试toCanIsTruthyOps
这种转换是。
3) I suspect that the implicit value intCanTruthy
somehow might be used when the compiler tries the toCanIsTruthyOps
implicit conversion on 10
. 3)我怀疑当编译器在10
上尝试toCanIsTruthyOps
隐式转换时,可能会以某种方式使用隐式值intCanTruthy
。
But this is where I really get lost. 但这是我真正迷失的地方。 I just don't see how the implicit resolution process proceeds after this. 我只是没有看到隐含的解决方法过程如何进行。 What happens next ? 接下来发生什么 ? How and Why ? 怎么样,为什么?
In other words, I don't know what is the implicit resolution sequence that allows the compiler to find the implementation of the truthy
method when evaluating 10.truthy
. 换句话说,我不知道什么是隐式解析序列,它允许编译器在评估10.truthy
时找到truthy
方法的实现。
Questions : 问题 :
How will 10
be converted to some object which does have the correct truthy
method ? 如何将10
转换为具有正确truthy
方法的某个对象?
What will that object be ? 那个对象是什么?
Where will that object come from? 那个对象来自哪里?
Could someone please explain, in detail , how the implicit resolution takes place when evaluating 10.truthy
? 有人可以详细解释在评估10.truthy
时隐式解决方案是如何发生的吗?
How does the self-type { self => ...
in CanTruthy
play a role in the implicit resolution process ? CanTruthy
中的自我类型 { self => ...
CanTruthy
在隐式解决过程中发挥作用?
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait CanTruthy[A] { self =>
/** @return true, if `a` is truthy. */
def truthys(a: A): Boolean
}
object CanTruthy {
def apply[A](implicit ev: CanTruthy[A]): CanTruthy[A] = ev
def truthys[A](f: A => Boolean): CanTruthy[A] = new CanTruthy[A] {
def truthys(a: A): Boolean = f(a)
}
}
trait CanTruthyOps[A] {
def self: A
implicit def F: CanTruthy[A]
final def truthy: Boolean = F.truthys(self)
}
object ToCanIsTruthyOps {
implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A]) =
new CanTruthyOps[A] {
def self = v
implicit def F: CanTruthy[A] = ev
}
}
// Exiting paste mode, now interpreting.
defined trait CanTruthy
defined module CanTruthy
defined trait CanTruthyOps
defined module ToCanIsTruthyOps
Trying out the type class on 10
: 尝试10
上的类型类:
scala> import ToCanIsTruthyOps._
import ToCanIsTruthyOps._
scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({
case 0 => false
case _ => true
})
intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1@71780051
scala> 10.truthy
res6: Boolean = true
First of all, thanks for pasting a fully self-contained example. 首先,感谢您粘贴一个完全独立的示例。
How will
10
be converted to some object which does have the correcttruthy
method ? 如何将10
转换为具有正确truthy
方法的某个对象?
When calling a method on a value whose type A
does not supply that method, an implicit conversion must kick in, ie there must be a method or function in scope with signature A => B
with B
having the method in question ( truthy
). 当对类型A
不提供该方法的值调用方法时,必须启动隐式转换 ,即在范围内必须有方法或函数,其中签名A => B
其中B
具有所讨论的方法( truthy
)。 In the case of a conversion method, it may ask for additional implicit parameters which would be looked up accordingly. 在转换方法的情况下,它可能要求额外的隐含参数 ,这些参数将被相应地查找。
The conversion method is toCanIsTruthyOps
, made available by importing the contents of ToCanIsTruthyOps
. 转换方法是toCanIsTruthyOps
,通过导入ToCanIsTruthyOps
的内容使其可用。 The type B
in the aforementioned sentence then is CanTruthyOps
, and the conversion method is toCanIsTruthyOps
. 上述句子中的B
型是CanTruthyOps
,转换方法是toCanIsTruthyOps
。 It may be invoked by the compiler as long as the implicit type-class evidence parameter CanTruthy
is found. 只要找到隐式类型类证据参数CanTruthy
它就可以被编译器调用。 So since type A = Int
, the compiler has to find an implicit value of type CanTruthy[Int]
if the call 10.truthy
is going to be successful. 因此,由于type A = Int
,如果调用10.truthy
将成功,编译器必须找到CanTruthy[Int]
类型的隐式值。
It looks for such a value in several places. 它在几个地方寻找这样的价值。 It could be in the companion object of Int
(that doesn't exist) or the companion object of CanTruthy
, or it was explicitly imported into the current scope. 它可能位于Int
(不存在)的伴随对象或CanTruthy
的伴随对象中,或者显式导入到当前范围中。 Here, the last case is used. 这里使用最后一种情况。 You explicitly created the implicit value intCanTruthy
, and that value is now found. 您明确创建了隐式值intCanTruthy
,现在找到该值。 And that's it. 就是这样。
What will that object be ? 那个对象是什么?
There will be a temporary instance of CanTruthyOps
whose mere purpose is to call truthys
on the evidence type class value (your intCanTruthy
here). 将有一个CanTruthyOps
的临时实例,其目的仅仅是在证据类型类值上调用truthys
(这里是你的intCanTruthy
)。
Where will that object come from? 那个对象来自哪里?
It is found in the look-up for implicit conversions Int => CanTruthyOps[Int]
. 它在查找隐式转换时发现Int => CanTruthyOps[Int]
。 The conversion performs the instantiation of that object. 转换执行该对象的实例化。
Could someone please explain, in detail, how the implicit resolution takes place when evaluating
10.truthy
? 有人可以详细解释在评估10.truthy
时隐式解决方案是如何发生的吗?
See answer to first question above. 请参阅上面第一个问题的答案。 Or as explicit code: 或者作为显式代码:
type A = Int
val v: A = 10
val ev: CanTruthy[A] = intCanTruthy
val ops: CanTruthyOps[A] = ToCanIsTruthyOps.toCanIsTruthyOps(v)(ev)
ops.truthy
How does the self-type
{ self => ...
inCanTruthy
play a role in the implicit resolution process ?CanTruthy
中的自我类型{ self => ...
CanTruthy
在隐式解决过程中发挥作用?
It has nothing to do with the implicit resolution. 它与隐式解决方案无关。 Indeed, in your example of the trait CanTruthy
, the self
acts as an alias for this
and isn't even used, so you could just remove it. 事实上,在你们的例子trait CanTruthy
中, self
充当一个别名this
并没有使用连,所以你可以只将其删除。
The signature of the method that converts any A
to CanTruthyOps[T]
which has the truthy
method is: 将任何A
转换为具有truthy
方法的CanTruthyOps[T]
的方法的truthy
是:
implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A])
this means that it doesn't convert just any A
but only those for which there is a CanTruthy[A]
defined, which is what the implicit ev
parameter is for. 这意味着它不会转换任何A
而只会转换那些定义了CanTruthy[A]
的CanTruthy[A]
,这就是implicit ev
参数的用途。 This means that, as part of the process of mapping 10
to something that has a .truthy
method, also intCanTruthy
is looked up before the wrapping is done. 这意味着,作为将10
映射到具有.truthy
方法的事物的过程的一部分,在完成包装之前也会intCanTruthy
。 So by the time that 10
has been implicitly converted to something with a truthy
method, the intCanTruthy
instance will have already been looked up and stored away as the F
attribute of the CanTruthyOps
: 因此,当10
被隐式转换为具有truthy
方法的东西时, intCanTruthy
实例将被查找并作为CanTruthyOps
的F
属性存储起来:
implicit def F: CanTruthy[A] = ev
(actually I don't know why that implicit
is necessary there; truthy()
will turn to F
explicitly. (实际上我不知道为什么implicit
在那里是必要的; truthy()
将明确转向F
F.truthys(self)
As to how exactly implicit resolution works, you're better off looking up documentation that describes the process in detail. 至于隐式解析是如何工作的,最好还是查找详细描述该过程的文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.