I want to do define a function in scala that takes arguments in prefix notation:
sum i1 i2 i3 ... in
and returns and Int with the sum of all the provided args. Note that I don't want to use parentheses when I call the function.
My goal is to do something like sum i1 plus i2
but I want to start with something simpler first.
NOTE: You might say there is not purpose for doing this if you can use the + operator, but my goal is not to add numbers. I am just using this as a generic learning tool.
答案 0 :(得分:1)
在回答这个问题之前,我想指出scala首先是面向对象的语言,所以你想要定义的大多数函数实际上都是特定对象的方法。对于任何课程T
(不一定是Int
),我会更一般地给出答案。我还假设您想要在值列表中执行的操作可以迭代完成,因此sum 1 2 3
实际上与sum (sum 1 2) 3
相同,因此我假设您有一些reducer函数f: (T, T) => T
。
定义中缀运算符,以便您可以执行类似
的操作i1 and i2 and i3 ...
你只需要定义一个方法
and(that: T): T = f(this, that)
在您的班级T
上。如果您无法为类型添加方法(例如,如果您使用的是lib中的类,或Int
),则可以使用implicit wrapper类型:
implicit class ReducibleT(i: T) {
def and(j: T): f(i, j)
}
使用中缀转发器定义前缀运算符,例如
sum i1 and i2 and i3 ...
看来你做不到!这是因为像ident1 ident2 ident3
这样的表达式总是(据我所知)被解析为ident1.ident2(ident3)
,(除非ident2
以冒号结束,在这种情况下它被反转)。但是,您无法为类型T
定义所有可能标识符的方法(例如,对于Int
,您无法在对象上定义方法1
,因此sum 1 2
具有没有任何意义),所以这是不可能的。
然而,你几乎可以做得很好:
sum (i1) and i2 and i3 ...
在这种情况下,parens表示函数调用,因此它实际调用对象and
上的方法sum(i1)
(实际上是sum.apply(i1)
,因为所有函数都是对象apply
特殊方法def sum(i: T) = i
implicit class ReducibleT(i: T) {
def and(j: T): f(i, j)
}
)。这是一个例子:
sum i1 i2 i3 ...
现在,如果您理解了第二种情况,那么您无法做到就不足为奇了
sum (i1) (i2) (i3)
任一。我们必须限制自己
def sum(i: T) = i
implicit class ReducibleT(i: T) {
def apply(j: T) = f(i, j)
}
使用以下内容:
implicit def tAsReducer(i: T): T => T = f(i, _)
或者,为了混合一点,您可以使用隐式转换为函数:
"ja.v_,a"