由类型构造函数f
和适当类型F[_]
参数化的考虑方法A
def f[F[_], A](v: F[A]) = v
让我们尝试将其应用于new Bar
scala> class Bar
class Bar
scala> def f[F[_], A](v: F[A]) = v
def f[F[_], A](v: F[A]): F[A]
scala> f(new Bar)
^
error: no type parameters for method f: (v: F[A]): F[A] exist so that it can be applied to arguments (Bar)
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Bar
required: ?F[?A]
^
error: type mismatch;
found : Bar
required: F[A]
Bar
的错误形状不正确。
现在让我们添加从Bar
到List[Int]
的隐式转换>
scala> implicit def barToList(b: Bar): List[Int] = List(42) def barToList(b: Bar): List[Int] scala> f(new Bar) val res1: Any = Bar@56881196
但是,请注意,由于
res1
的运行时类是Bar
,而不是List
,因此似乎并未实际应用隐式转换。此外,res1
的编译时类型是Any
,而不是List[Int]
。查看-Xprint:typer
的输出,我们看到类似
val res1: Any = f[Any, Nothing](new Bar())
我们看到以下推论的地方
F[_] = Any A = Nothing
相对于
F[_] = List A = Int
并且我们看到实际上没有发生任何转换,也就是说,我们没有看到类似的东西
f(barToList(new Bar()))
为什么仅隐式转换的存在使程序得以编译,而实际上未应用任何隐式转换?请注意,当明确说明类型参数时,它会按预期工作]
scala> f[List, Int](new Bar) val res2: List[Int] = List(42)
考虑方法f,它由类型构造函数F [_]和适当的类型A参数化def f [F [_],A](v:F [A])= v让我们尝试将其应用于新的Bar scala > class Bar class Bar scala> def f [F [...
我之前已经注意到此问题,我认为可以在编译器中将其追溯到this code:
// Then define remaining type variables from argument types.
foreach2(argtpes, formals) { (argtpe, formal) =>
val tp1 = argtpe.deconst.instantiateTypeParams(tparams, tvars)
val pt1 = formal.instantiateTypeParams(tparams, tvars)
// Note that isCompatible side-effects: subtype checks involving typevars
// are recorded in the typevar's bounds (see TypeConstraint)
if (!isCompatible(tp1, pt1)) {
throw new DeferredNoInstance(() =>
"argument expression's type is not compatible with formal parameter type" + foundReqMsg(tp1, pt1))
}
}
val targs = solvedTypes(tvars, tparams, varianceInTypes(formals), upper = false, lubDepth(formals) max lubDepth(argtpes))