由于 Scala 2.12(或者是 2.13,不能确定),编译器可以跨多个方法推断潜在类型参数:
def commutative[
A,
B
]: ((A, B) => (B, A)) = {???} // implementing omitted
val a = (1 -> "a")
val b = commutative.apply(a)
最后一行成功推断A = Int, B = String
,不幸的是,这需要a: (Int, String)
给出一个实例。
现在我想稍微扭曲一下这个 API 并定义以下函数:
def findApplicable[T](fn: Any => Any)
这样可以findApplicable[(Int, String)](commutative)
自动生成专用于A = Int, B = String
. 有没有办法在语言的能力范围内做到这一点?或者我必须升级到 scala 3 才能做到这一点?
UPDATE 1应该注意,commutative 的输出可以是任何类型,不一定是 Function2,例如我尝试了以下定义:
trait SummonedFn[-I, +O] extends (I => O) {
final def summon[II <: I]: this.type = this
}
然后重新定义commutative
使用它:
def commutative[
A,
B
]: SummonedFn[(A, B), (B, A)] = {???} // implementing omitted
val b = commutative.summon[(Int, String)]
糟糕,这不起作用,类型参数没有像值参数一样得到同等对待