scala - 从返回类型推断泛型隐式参数的类型

标签 scala types implicits implicit-typing

说我有一个像这样的简单类(class)

abstract class Foo {
  implicit val impInt: Int = 42
  def f[A]()(implicit a: A): A
  val f2: Int = f()
}

声明 val 时 f2 , 编译器能够推断出函数 f 的隐式参数的类型是 Int因为那个类型和结果类型是一样的,结果类型需要匹配值的类型f2 , 即 Int .

然而,抛出一个 Ordering[A]混合:
def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()

导致此编译错误:

Ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and method $conforms in object Predef of type [A]=> <:<[A,A] match expected type A



如果我在调用 f() 时添加类型信息,它编译:
val f2: Int = f[Int]()

首先,我遇到了隐式排序的情况,我认为这与 Scala 从左到右推断有关;我认为它无法先匹配返回类型,然后推断 f 的(隐式)参数类型.但是后来我在没有隐式排序的情况下尝试了这个案例,发现它有效 - 它推断出 f必须由 Int 参数化因为返回类型必须是 Int (因为 f2Int )。

请注意,如果我们删除 implicit a: A并只留下 Ordering 隐式参数,错误仍然存​​在,但变为

Diverging implicit expansion for type Ordering[A] starting with method Tuple9 in object Ordering.



再次添加类型参数,使其成为 val f2: Int = f[Int]()有帮助。

这是怎么回事?为什么编译器可以推断出该参数 A必须是 Int ,但不是那个参数 Ordering[A]必须是 Ordering[Int] ?

最佳答案

生成排序实例的方式一定有问题,因为下面的代码有效。我会报告一个错误。

case object types {
  implicit def buh[X]: List[X] = List()
}
abstract class Foo {

  import types._

  def f[A]()(implicit l: List[A]): A
  val f2: Int = f()
}

关于scala - 从返回类型推断泛型隐式参数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36388954/

相关文章:

function - scala隐式类方法类型不匹配在reduce与函数currying的非隐式方法中

arrays - 如何在Scala中高效地将阵列复制到另一个阵列?

scala - Play 2.0 中的 stub Controller

scala - Scala 中的运算符优先级

php - 在 Symfony 2 类型中禁用选择字段的后端验证

java - 为什么从接口(interface)执行方法时会将参数转换为 Object(或扩展 YourObject)?

scala - Scala 集合中的森林砍伐

多个隐式参数的Scala解析

Scala 集 : + vs.++

javascript - 有什么好的 JavaScript 货币或十进制类吗?