我正在爲我在Scala中構建的實驗庫開發DSL,並且遇到了一些令人煩惱的Scala類型推理特性,因爲它涉及到lambda表達式參數似乎沒有在書Programming In Scala。複雜的Scala類型推理w/Lambda表達式
在我的庫中,我有一個特徵Effect [-T],用於表示可以應用於T類型對象的臨時修飾符。我有一個對象myEffects,它有一個名爲+ =接受類型爲Effect [PlayerCharacter]的參數。最後,我有一個泛型方法,當[T]用於通過接受條件表達式和另一個效果作爲參數來構造條件效果時。簽名是如下:
def when[T](condition : T => Boolean) (effect : Effect[T]) : Effect[T]
當我所說的「時」的方法與上述簽名,傳遞它的結果到+ =方法,它是無法推斷的參數lambda表達式的類型。
myEffects += when(_.hpLow()) (applyModifierEffect) //<-- Compiler error
如果我將「when」的參數組合到單個參數列表中,Scala能夠推斷出lambda表達式的類型就好了。
def when[T](condition : T => Boolean, effect : Effect[T]) : Effect[T]
/* Snip */
myEffects += when(_.hpLow(), applyModifierEffect) //This works fine!
它也適用,如果我完全刪除第二個參數。然而,出於美學的原因,我真的希望將參數作爲單獨的參數列表傳遞給「when」方法。
我從Programming in Scala的第16.10節中瞭解到,編譯器首先查看方法類型是否已知,如果是,則使用它來推斷它的參數的預期類型。在這種情況下,最外面的方法調用是+ =,它接受類型爲Effect [PlayerCharacter]的參數。由於[T]爲Effect [T]的返回類型以及要傳遞結果的方法需要Effect [PlayerCharacter]類型的參數,因此可以推斷出T是PlayerCharacter,因此lambda的類型表達式作爲第一個參數傳遞給「when」是PlayerCharacter => Boolean。這似乎是它在一個參數列表中提供參數時的工作方式,那麼爲什麼將參數分成兩個參數列表會將其分開呢?
http://pchiusano.blogspot.com/2011/05/making-most-of-scalas-extremely-limited.html – retronym