Scala 确保块中的隐式转换失败

Failed implicit conversion in scala ensuring block

我正在使用 scalac 2.12.1 在没有任何选项的情况下编译以下程序:

import scala.language.implicitConversions

case class Int32(v : Int) {
}
case class Int64(v : BigInt) {
    def > (that : Int64) = this.v > that.v
    def <= (that : Int64) = this.v <= that.v
}
object implicits {
    implicit def int32Toint64(input : Int32) = Int64(BigInt(input.v))
}
import implicits._

class myTest {
    def max(x: Int64, y: Int32) : Int64 = {
        if (x > y)
            x
        else
            y  // If this is replaced with int32Toint64(y) it works !
    } ensuring(res => x <= res && y <= res) // <= error: missing parameter type for 'res'
}

以上程序编译失败,出现注释中指出的错误。 我的期望是隐式转换 int32Toint64 会自动生效。请注意,如果我明确地进行转换,即如果我将 y 替换为 int32Toint64(y),则程序编译成功。所以我很疑惑。为什么我会看到这种行为?有没有办法在没有显式转换的情况下防止这个错误?

谢谢!

这个有效:

class myTest {
    def max(x: Int64, y: Int32) : Int64 = {
        if (x > y)
            x
        else
            (y : Int64)
    } ensuring(res => x <= res && y <= res)
}

这也有效:

class myTest {
    def max(x: Int64, y: Int32) : Int64 = ({
        if (x > y)
            x
        else
            y
    }: Int64) ensuring(res => x <= res && y <= res)
}

这显然行不通:

class myTest {
    def max(x: Int64, y: Int32) : Int64 = {
        if (x > y)
            x
        else
            y
    } ensuring((res: Int64) => x <= res && y <= res)
}

为什么?孤立地看这个表达式:

    {
        if (x > y)
            x
        else
            y
    }

如果未明确指定类型,编译器可能从中得出什么?它会派生出类似 Serializable,甚至 AnyRef 的东西。它还能做什么?类型检查器以非常直接的方式工作。它只是查看一个表达式,尝试导出它的最精确类型,如果没有从外部指定类型,它不会尝试隐式转换任何内容。而且它不会开始在代码的偏远角落搜索其他类型提示。在这种情况下,ensuring ( ... ) 既不是该表达式的一部分,也不允许显式 return 类型归属 : Int64 = 向下渗透。

我想理解为什么这很明显的最好方法是为简单类型的 lambda 演算编写一个小的类型检查器:它非常简单,但在类似情况下已经表现出完全相同的行为。