斯卡拉沒有多態功能,例如Haskell做的。函數類型總是具體的。只有方法可以是多態的。不幸的是,您的假設類型(x: Foo) => x.Bar
在Scala中不可表達。
這種轉換的通用方法與函數時變得很明顯:所有類型的信息丟失:
scala> def foo[Bar](x: Bar): Bar = ???
foo: [Bar](x: Bar)Bar
scala> foo _
res1: Nothing => Nothing = <function1>
您可能也注意到,Scala並未能轉換的方法與相關類型的功能。這是因爲它是不可能滿足你的假設類型:
scala> def foo(x: Foo): x.Bar = ???
foo: (x: Foo)x.Bar
scala> foo _
<console>:10 error: method with dependent type (x: Foo)x.Bar cannot be converted
to function value.
另見this和this問題。
然而,有幾個解決方案,您的問題。其中之一是封裝的依賴性輸入法的幫手特點:
trait FooFunc {
def apply(x: Foo): x.Bar
}
def compareOutput(x1: Foo, x2: Foo)(f: FooFunc)(comparer: ...) = {
val y1 = f(x1)
val y2 = f(x2)
comparer(y1,y2)
}
然後,您可以創建可傳遞到您的compareOutput
方法FooFunc的實例。
請參閱示例[Miles Sabin如何在無形中使用依賴方法類型](https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/syntax/hlists.scala) 。 –
我不認爲這是相關的。他希望能夠定義一個函數類型(而不僅僅是定義一個方法),其中返回類型取決於參數值。我相信這目前是不可能的。即使你設法定義一個匹配OP意圖的類型,我不認爲你能夠將一個方法作爲參數'f'來傳遞,因爲eta-expansion不支持依賴方法類型。請參閱https://issues.scala-lang.org/browse/SI-4751。這會迫使我們以一種相當尷尬的方式來定義這些「依賴函數」,比如擴展一個自定義特徵並實現其「應用」方法。 –
@RégisJean-Gilles:你說得對 - 我可能讀得太快了。你所描述的可以通過Shapeless的多態函數值來完成,但不是vanilla Scala函數。 –