2016-01-21 85 views
5

使用命名參數,用咖喱功能。我在那獲取塊使用4個參數的方法。在每個塊,第一個參數始終是相同的:如何在斯卡拉

// Block 1 - first parameter always "A" 
foo(a="A", b="x", c="y", d="z") 
foo(a="A", b=".", c=",", d="-") 
foo(a="A", b="1", c="2", d="3") 

// Block 2 - first parameter always "B" 
foo(a="B", b="x", c="y", d="z") 
foo(a="B", b=".", c=",", d="-") 
foo(a="B", b="1", c="2", d="3") 

我想要一個快速的方法來創建每個塊的方法,這樣我只需要指定其他3個參數。目前我可以做到這一點:

def fooCurried(a: String) = foo(a, _: String, _: String, _: String) 

val fooA = fooCurreid("A") 
fooA("x", "y", "z") 
fooA(".", ",", "-") 
fooA("1", "2", "3") 

val fooB = fooCurried("B") 
fooB("x", "y", "z") 
fooB(".", ",", "-") 
fooB("1", "2", "3") 

這種方法的問題是,我失去了我的命名參數。他們成爲v1v2v3。使用命名參數,因爲類型的其他3個參數都是一樣的,因此很容易混淆在這種情況下非常重要。

有沒有乾淨的方式來定義一個fooCurried功能像上面我可以很容易地在不同的情況下使用,但讓我用命名的參數?

我想的東西我可以用這樣的:

def fooCurried(a: String) = ??? 

val fooA = fooCurreid("A") 
fooA(b="x", c="y", d="z") 
fooA(b=".", c=",", d="-") 
fooA(b="1", c="2", d="3") 

提前感謝!在這裏你可以使用case class

+2

嗯,我會說這是不討好部分應用程序。如果你想讓它變成咖啡,你可以將它定義爲例如'def foo(a:String)(b:String,c:String,d:String)= ???'。 –

+0

@MateuszKubuszok是使用不正確的術語遺憾。在這種情況下,我不控制'foo',所以我不能用你所建議的格式來改變它。我可以做一個包裝。 – rmin

回答

4

如何:

case class fooCurried(a: String) { 
    def apply(b: String, c: String, d: String) = { 
    // do something 
    println(a + "," + b + "," + c + "," + d) 
    } 
} 

您可以使用它像這樣:

scala> val fooA = fooCurried(a = "A") 
fooA: fooCurried = fooCurried(A) 

scala> fooA(b="B", c="C", d="D") 
A,B,C,D 

scala> fooA(b="x", c="y", d="z") 
A,x,y,z 
+0

這也避免了昂貴的匿名類 – Clashsoft

+0

@Clashsoft你能對你的意思,避免昂貴的匿名類什麼詳細點嗎? – rmin

1

一種替代方法:

case class Foo(a:String, b:String, c:String) 

val f = Foo(a="a", b="b", c="c") 
foo(f.copy(b ="b1", c="c1")) 

但隨後你foo會採取一個類作爲參數,而不是4個多串。