简体   繁体   English

这个“简单”ScalaZ教程代码示例中的隐式解析序列是什么?

[英]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)隐含值intCanTruthyCanTruthy[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.truthytoCanIsTruthyOps隐式转换方法在范围内,因此当编译器看到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 correct truthy 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 => ... in CanTruthy 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实例将被查找并作为CanTruthyOpsF属性存储起来:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM