2016-01-21 4 views
5

Ich habe eine Methode mit 4 Parametern, die in Blöcken verwendet wird. Innerhalb jeden Blockes ist der erste Parameter immer gleich:Wie benannte Parameter mit einer Curry-Funktion in der Scala verwendet werden

// 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") 

ich eine schnelle Art und Weise will ein Verfahren für jeden Block zu erstellen, so dass ich nur die anderen drei Parameter angeben muß. Derzeit kann ich das tun:

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") 

Das Problem mit diesem Ansatz ist, dass ich meine benannten Parameter verlieren. Sie werden v1, v2 und v3. Die Verwendung benannter Parameter ist in diesem Fall wichtig, da die Typen der anderen 3 Parameter gleich sind und daher leicht verwechselt werden können.

Gibt es eine saubere Möglichkeit, eine fooCurried Funktion wie oben zu definieren, die ich leicht in verschiedenen Kontexten verwenden kann, aber lässt mich benannte Parameter verwenden?

Ich würde etwas wie ich so verwenden kann:

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") 

Vielen Dank im Voraus!

+2

Nun, ich würde sagen, dass es teilweise Anwendung ist currying nicht. Wenn Sie möchten, dass es curiert wird, würden Sie es als z. 'def foo (a: String) (b: String, c: String, d: String) = ???'. –

+0

@MateuszKubuszok Ja Entschuldigung für die Verwendung falscher Terminologie. In diesem Fall kontrolliere ich 'foo' nicht, also kann ich es nicht mit dem von dir vorgeschlagenen Format ändern. Ich könnte aber einen Wrapper machen. – rmin

Antwort

4

Wie wäre es damit:

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

Sie es wie folgt verwenden können:

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

Dies vermeidet auch eine teure anonyme Klasse – Clashsoft

+0

@Clashsoft Können Sie erläutern, was Sie meinen, indem Sie eine teure anonyme Klasse vermeiden? – rmin

1

Eine alternative Art und Weise, wo Sie case class verwendet werden:

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")) 

Aber dann foo würde anstelle von 4 mehrere Strings eine Klasse als Argument.

Verwandte Themen