从返回类型推断通用隐式参数的类型 [英] Inferring type of generic implicit parameter from return type

查看:110
本文介绍了从返回类型推断通用隐式参数的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个像这样的简单班级

Say I have a simple class like this

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.

When declaring val f2, compiler is able to infer that the type of implicit parameter of function f is Int because that type is the same as the result type, and result type needs to match the type of value f2, which is Int.

但是,将Ordering[A]放入混合中:

def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()

导致此编译错误:

模棱两可的隐式值:类型为>>的对象Predef中的值StringCanBuildFrom = scala.collection.generic.CanBuildFrom [String,Char,String]和方法$ conforms在类型为[A] =>的对象Predef中. [A,A]匹配预期的类型A

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()时添加类型信息,它将编译:

If I add the type information when invoking f(), it compiles:

val f2: Int = f[Int]()

首先,我遇到了隐式排序的情况,我认为这与Scala从左到右进行推断有关;我认为它不能首先匹配返回类型,然后然后推断f的(隐式)参数类型.但是后来我尝试了这种情况,没有隐式排序,并且看到了它的工作原理-推断f必须由Int参数化,因为返回类型必须为Int(因为f2Int) .

First I encountered the case with implicit ordering and I thought it has to do with Scala inferring left-to-right; I thought it's not able to match the return type first and then infer the (implicit) parameter type of f. But then I tried the case without implicit ordering and saw that it works - it inferred that f must be parameterized by Int because the return type has to be an Int (because f2 is an Int).

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

Note that if we remove implicit a: A and leave only the Ordering implicit parameter, the error remains, but becomes

从对象Ordering中的Tuple9方法开始,对Ordering [A]类型进行隐式展开.

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

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

Again, adding type parameter so that it becomes val f2: Int = f[Int]() helps.

这是怎么回事?为何编译器可以推断参数A必须是Int,而不是参数Ordering[A]必须是Ordering[Int]?

What's going on? Why can the compiler infer that parameter A must be an Int, but not that parameter Ordering[A] must be an Ordering[Int]?

推荐答案

订购实例的生成方式一定存在问题,因为下面的代码有效.我会报告一个错误.

There must be something wrong with the way ordering instances are generated, as the code below works. I'd report a bug.

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()
}

这篇关于从返回类型推断通用隐式参数的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆