給出。如果我們着眼於特定類型兼容Scala編譯器,來源可以幫助我們理解問題所在。我從來沒有對Scala編譯器做過貢獻,但我發現這些源代碼非常易讀,而且我已經對此進行了研究。
負責類型推斷的類是scala.tools.nsctypechecker.Infer
,您可以通過在Scala編譯器源中查找錯誤的一部分來簡單地找到它。你會發現下面的代碼片段:
/** error if arguments not within bounds. */
def checkBounds(pos: Position, pre: Type, owner: Symbol,
tparams: List[Symbol], targs: List[Type], prefix: String) = {
//@M validate variances & bounds of targs wrt variances & bounds of tparams
//@M TODO: better place to check this?
//@M TODO: errors for getters & setters are reported separately
val kindErrors = checkKindBounds(tparams, targs, pre, owner)
if(!kindErrors.isEmpty) {
error(pos,
prefix + "kinds of the type arguments " + targs.mkString("(", ",", ")") +
" do not conform to the expected kinds of the type parameters "+ tparams.mkString("(", ",", ")") + tparams.head.locationString+ "." +
kindErrors.toList.mkString("\n", ", ", ""))
}
所以,現在的點是理解爲什麼checkKindBounds(tparams, targs, pre, owner)
返回這些錯誤。如果你走在方法調用鏈,你會看到checkKindBounds調用另一個方法
val errors = checkKindBounds0(tparams, targs, pre, owner, true)
你會看到這個問題被連接到檢查更高kinded類型的界限,在線路5784,裏面checkKindBoundsHK:
if (!sameLength(hkargs, hkparams)) {
if (arg == AnyClass || arg == NothingClass) (Nil, Nil, Nil) // Any and Nothing are kind-overloaded
else {error = true; (List((arg, param)), Nil, Nil) } // shortcut: always set error, whether explainTypesOrNot
}
測試不通過,它出現在我的調試器:
hkargs$1 = {[email protected]}"List()"
arg$1 = {[email protected]}"class List"
param$1 = {[email protected]}"type B"
paramowner$1 = {[email protected]}"method process"
underHKParams$1 = {[email protected]}"List(type R)"
withHKArgs$1 = {[email protected]}"List()"
exceptionResult12 = null
hkparams$1 = {[email protected]}"List(type R)"
所以它看起來像有一個更高的kinded PARAM,R型,但沒有提供d值。
如果你真的回去給checkKindBounds,你看到片段後:
val (arityMismatches, varianceMismatches, stricterBounds) = (
// NOTE: *not* targ.typeSymbol, which normalizes
checkKindBoundsHK(tparamsHO, targ.typeSymbolDirect, tparam, tparam.owner, tparam.typeParams, tparamsHO)
)
的arityMismatches
包含一個元組列表,B.現在你還可以看到錯誤消息是錯誤的:
推斷種類型參數(MyFoo,MyFoo,列表[X])不 符合預期的種類型的參數(F型,型 R,B型)的。列表[X]的類型參數不匹配B型的預期 參數:類List有一種類型的參數,但B型有ZERO
事實上,如果你在下面放一個斷點行5859調用
checkKindBoundsHK(tparamsHO, targ.typeSymbolDirect, tparam, tparam.owner, tparam.typeParams, tparamsHO)
你可以看到,
tparam = {[email protected]}"type B"
targ = {[email protected]}"List[X]"
結論:
由於某些原因,在處理諸如您的複雜高級類型時,Scala編譯器推斷受到限制。我不知道它來自哪裏,也許你想發送一個bug到編譯器團隊
我正在使用scala 2.9.3-20120917-121530-db16547873 –