特定
trait Foo {
type Bar
}
Run Code Online (Sandbox Code Playgroud)
是否有合法的方法来编写类似的东西f: (x: Foo) => x.Bar,以便函数的返回类型取决于参数?使用的一个例子是
def compareOutput(x1: Foo, x2: Foo)(f: (x: Foo) => x.Bar /* illegal */)(comparer: (x1.Bar, x2.Bar) => Boolean) = {
val y1 = f(x1)
val y2 = f(x2)
comparer(y1, y2)
}
Run Code Online (Sandbox Code Playgroud)
Scala不具有多态函数,例如Haskell.函数类型总是具体的.只有方法可以是多态的.不幸的是,这意味着您的假设类型(x: Foo) => x.Bar在Scala中无法表达.
将泛型方法转换为函数时,这一点很明显:所有类型信息都丢失了:
scala> def foo[Bar](x: Bar): Bar = ???
foo: [Bar](x: Bar)Bar
scala> foo _
res1: Nothing => Nothing = <function1>
Run Code Online (Sandbox Code Playgroud)
您可能还注意到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.
Run Code Online (Sandbox Code Playgroud)
但是,您的问题有几种解决方案.一种方法是将依赖类型的方法封装在辅助特征中:
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)
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以创建FooFunc的实例,您可以将其传递给您的compareOutput方法.