鉴于以下特点:
scala> trait Foo {
| def f: Int => Int => Int
| }
defined trait Foo
我创建了一个试图实例化Foo#f
的类:
scala> class FooImpl extends Foo {
| override def f(x: Int, y: Int) = 100
| }
<console>:11: error: class FooImpl needs to be abstract, since method f in trait Foo of type => Int => (Int => Int) is not defined
class FooImpl extends Foo {
^
我能用以下方法解决它:
scala> class FooImpl extends Foo {
| override def f = x => y => 100
| }
defined class FooImpl
然后我可以创建一个实例:
scala> new FooImpl().f(10)(20)
res3: Int = 100
但是,我如何创建一个Foo
的实现,用[{1}}实现Foo#f
,即不用curry?
最后,我试过了:
def f(x: Int, y: Int) = 100
但那也失败了:
scala> trait Bar { def f: (Int, Int) => Int }
defined trait Bar
答案 0 :(得分:7)
这些类型不兼容。
def f: Int => Int => Int
..是一个无参数方法,返回带有一个参数Int
的函数,它返回一个带有一个参数Int
的函数,返回Int
。
def f: (Int, Int) => Int
..是一个无参数方法,它返回一个带有Int
类型参数的函数,返回Int
。
def f(x: Int, y: Int): Int
..是一个带有两个Int
参数的双参数方法,返回Int
。
所有这些都是根本不同的。你不能用任何其他方式覆盖它们中的任何一个。如果您想要f(x: Int, y: Int): Int
,那么首先应该是Foo
中的签名。否则,你必须进行咖喱,eta-expand或其他东西才能使签名匹配。
答案 1 :(得分:0)
如果你想让特性定义非咖喱版本,那么它需要是这样的:
trait Foo {
def f(x: Int, y: Int): Int
}
此处(x: Int, y: Int)
表示f
接受Int
的两个参数,: Int
表示返回值必须为Int
。
答案 2 :(得分:0)
这是如何创建实现FooImpl
特征的Foo
。我们也可以在没有currying的情况下访问Foo #f。
trait Foo{
def f1:Int=> Int=> Int
def f2: (Int, Int) => Int
}
class FooImpl extends Foo{
//actual implementors of f1 and f2 in Foo trait
def g0=g1
def g1=g2
def g2=20
def add(a:Int, b:Int)=a+b
override def f1=g0=>g1=>g2
override def f2=add
}
现在我们可以实例化FooImpl
类,而不必讨论。
var x = new FooImpl
println(x.f1.apply(1).apply(1)) //results 20
println(x.f2(10,10)) //results 20