我有一个带有两个参数列表的函数,我试图部分应用这些函数并与curring一起使用。第二个参数列表包含均具有默认值(但不是隐式的)的参数。像这样的东西:
def test(a: Int)(b: Int = 2, c: Int = 3) { println(a + ", " + b + ", " + c); }
现在,以下内容就可以了:
test(1)(2, 3);
test(1)(2);
test(1)(c=3);
test(1)();
现在,如果我定义:
def partial = test(1) _;
然后可以执行以下操作:
partial(2, 3);
有人可以解释为什么我不能在“partial”中省略一些/所有参数,如下所示:
partial(2);
partial(c=3);
partial();
写“partial”的行为不应该与“test(1)”本质上相同吗?有人可以帮我找出实现此目标的方法吗?
请帮忙,我很拼命!
编辑-由于我无法在24小时内回答自己的问题,因此我将在此处发布自己的答案:
到目前为止,这是我能做的最好的事情:
class Test2(val a: Int) {
def apply(b: Int = 2, c: Int = 3) { println(a + ", " + b + ", " + c); }
}
def test2(a: Int) = new Test2(a);
def partial2 = test2(1); // Note no underscore
test2(1)(2, 3);
test2(1)(2);
test2(1)(c=3);
test2(1)();
partial2(2, 3)
partial2(2);
partial2(c=3);
partial2();
这样工作...
最佳答案
类型推断引擎将接下来的内容提供给partial
。即eta扩展test(1) _
。您可以看到例如在REPL中,partial
的类型为(Int, Int) => Unit
,而test
的类型为(a: Int)(b: Int,c: Int)Unit
。 eta扩展的结果是一个Function
对象,该对象不附带任何参数名称(因为可以使用匿名参数定义Function
)。
要解决此问题,您必须定义partial
,如下所示:
def partial(b: Int = 2, c: Int = 3) = test(1)(b,c)
也许您需要排除
test
和partial
都可以到达的默认值,以确保它们保持相等。但是我知道避免重复参数的名称而不引入额外的开销(如创建新对象等)是没有技巧的。
关于Scala- curry 和默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5676301/