4

所以基本上我想寫可以寫成這樣的功能:斯卡拉不處理不顯式類型爲封「:」功能

{ println(_) } =: thing 

在這裏,我希望它實際上做thing.=:(println(_))。比方說,爲求論點,即=:具有以下實現:

def =:(block : Int => Any) { 
    block(5) 
} 

所以我嘗試調用它上面的方法,我也得到:

<console>:10: error: type mismatch; 
    found : Unit 
    required: Int => Any 
      println(_) =: thing 

我再試試這樣做:

thing.=:(println(_)) 

這樣我就能得到一個很好的5打印到終端。然後我試了這個:

{ value => println(value) } =: thing 

這又失敗了,並告訴我有一個「缺少參數類型」。我猜這是因爲Scala試圖在這種情況下首先解析/編譯函數參數,並且當它被稱爲更傳統的方式時(不知道它是什麼類型)(我完全猜到了)點運算符)。

任何人都可以在這裏發現更多的問題,也可能建議實現某些東西接近我最初的目標的最佳方式?

P.S.對於標題感到抱歉。一旦我對問題有了更好的理解,我會重新命名它。

回答

6

類型推理從左到右工作,即使#:表單的符號方法名稱最終從右到左工作。您可以使用一個輔助方法,如果你真的只有一個類型:

def let(fi: Int => Any) = fi 
case class Thing(i: Int) { 
    def =:(f: Int => Any) = f(i) 
} 

scala> let(_+2) =: Thing(5) 
res4: Any = 7 

但是這並不是一個完全令人滿意的解決辦法,如果你有很多可能的類型簽名,因爲你必須在左邊匹配的輔助方法名所需的類型在右側。

+0

無論如何要用隱式函數來實現這個嗎?我猜不是因爲Scala不會尋找隱含的,因爲沒有類型而不是錯配。此外,如果你知道一個原因,你可以添加到你的答案,爲什麼類型推斷不能正確地左對這些功能。 – seadowg

+0

@Oetzi - 將類型推理器從右向左工作會更有幫助。原則上沒有理由不能做到這一點;它只是實施的一個限制。 –

1

那麼,爲什麼你不加參數類型:

{ value:Int => println(value) } =: thing 

我不是一個專家斯卡拉自己,所以我不能提供什麼樣的inferencer可以在無法推斷更深的解釋。

+0

這樣做的工作,但我正在寫一個DSL,其中每個關閉將具有相同的輸入類型,所以它會相當單調。 – seadowg