3 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超6個(gè)贊
我同意推斷“唯一可能的”類(lèi)型會(huì)很好,即使調(diào)用是鏈接在一起的,但存在技術(shù)限制。
您可以將推理視為對(duì)表達(dá)式的廣度優(yōu)先掃描,收集對(duì)類(lèi)型變量的約束(由子類(lèi)型邊界和必需的隱式參數(shù)引起),然后求解這些約束。這種方法允許例如隱式指導(dǎo)類(lèi)型推斷。在您的示例中,即使僅查看xs.toSet
子表達(dá)式也有一個(gè)解決方案,但是以后的鏈接調(diào)用可能會(huì)引入使系統(tǒng)無(wú)法滿(mǎn)足的約束。保留類(lèi)型變量未解決的缺點(diǎn)是,對(duì)閉包的類(lèi)型推斷需要知道目標(biāo)類(lèi)型,因此將失?。ㄋ枰鲆恍┚唧w的事情-所需的閉包類(lèi)型及其參數(shù)類(lèi)型必須并非兩者都是未知的)。
現(xiàn)在,當(dāng)延遲解決約束使推理失敗時(shí),我們可以回溯,解決所有類(lèi)型變量,然后重試,但是實(shí)現(xiàn)起來(lái)很棘手(可能效率很低)。

TA貢獻(xiàn)1871條經(jīng)驗(yàn) 獲得超8個(gè)贊
類(lèi)型推斷無(wú)法正常工作,因?yàn)長(zhǎng)ist#toSetis 的簽名
def toSet[B >: A] => scala.collection.immutable.Set[B]
并且編譯器需要在調(diào)用中的兩個(gè)位置推斷類(lèi)型。在函數(shù)中注釋參數(shù)的另一種方法是toSet使用顯式類(lèi)型參數(shù)進(jìn)行調(diào)用:
xs.toSet[Int] map (_*2)
更新:
關(guān)于您的問(wèn)題,為什么編譯器可以分兩步進(jìn)行推斷,讓我們看一下一一行地輸入行時(shí)會(huì)發(fā)生什么:
scala> val xs = List(1,2,3)
xs: List[Int] = List(1, 2, 3)
scala> val ys = xs.toSet
ys: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
在這里,編譯器會(huì)推斷出最具體類(lèi)型,ys這是Set[Int]在這種情況下?,F(xiàn)在已經(jīng)知道這種類(lèi)型,因此map可以推斷傳遞給函數(shù)的類(lèi)型。
如果在示例中填寫(xiě)了所有可能的類(lèi)型參數(shù),則調(diào)用將寫(xiě)為:
xs.toSet[Int].map[Int,Set[Int]](_*2)
第二個(gè)type參數(shù)用于指定返回的集合的類(lèi)型(有關(guān)詳細(xì)信息,請(qǐng)查看Scala集合的實(shí)現(xiàn)方式)。這意味著我什至低估了編譯器必須推斷的類(lèi)型數(shù)量。
在這種情況下,似乎很容易推斷出來(lái),Int但在某些情況下卻并非如此(鑒于Scala的其他功能,例如隱式轉(zhuǎn)換,單例類(lèi)型,混合的特性等)。我并不是說(shuō)這無(wú)法完成-只是Scala編譯器沒(méi)有做到這一點(diǎn)。
- 3 回答
- 0 關(guān)注
- 477 瀏覽
添加回答
舉報(bào)