我想要做的定義Scala中的一個函數,它的參數在前綴符號:定義函數,它的參數在前綴符號斯卡拉
sum i1 i2 i3 ... in
,並返回和Int與所提供的所有參數的個數之和。請注意,我不想在調用函數時使用括號。
我的目標是做類似sum i1 plus i2
的事情,但我想先從簡單一點開始。
注意:如果您可以使用+運算符,您可能會說沒有這樣做的目的,但我的目標不是添加數字。我只是將其用作通用學習工具。
我想要做的定義Scala中的一個函數,它的參數在前綴符號:定義函數,它的參數在前綴符號斯卡拉
sum i1 i2 i3 ... in
,並返回和Int與所提供的所有參數的個數之和。請注意,我不想在調用函數時使用括號。
我的目標是做類似sum i1 plus i2
的事情,但我想先從簡單一點開始。
注意:如果您可以使用+運算符,您可能會說沒有這樣做的目的,但我的目標不是添加數字。我只是將其用作通用學習工具。
在回答這個問題之前,我想指出scala首先是一個面向對象的語言,因此大多數您想定義的函數實際上都是特定對象上的方法。我將給出任何類別T
(不一定代表Int
)的更一般性的答案。我還假設你想在你的值列表上做什麼可以迭代完成,所以sum 1 2 3
實際上與sum (sum 1 2) 3
相同,所以我假設你有一些減速函數f: (T, T) => T
。
定義中綴操作符,讓你可以這樣做
i1 and i2 and i3 ...
,你只需要在你的T
類中定義的方法
and(that: T): T = f(this, that)
。如果你不能夠方法添加到您的類型(例如,如果您正在使用從一個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 ...
在這種情況下,括號表示函數調用,所以它實際上調用該對象sum(i1)
的方法and
(實際上是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, _)
你接受'i1 plus i2 plus ...'?這是更簡單的... –
這將是很高興知道如何定義。儘管我現在對前綴符號調用更感興趣。如果你可以展示你的例子可以做的話,我們將不勝感激。謝謝 – locorecto