2016-01-21 27 views
5

Ho un metodo con 4 parametri che viene utilizzato nei blocchi. All'interno di ogni blocco, il primo parametro è sempre lo stesso:Come utilizzare i parametri denominati con una funzione aleatoria in scala

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

Voglio un modo rapido per creare un metodo per ogni blocco in modo che ho solo bisogno di specificare gli altri 3 parametri. Attualmente posso farlo:

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

Il problema con questo approccio è che perdo i miei parametri nominati. Diventano v1, v2 e v3. L'utilizzo dei parametri denominati è importante in questo caso perché i tipi degli altri 3 parametri sono gli stessi e quindi sono facili da mescolare.

C'è un modo pulito per definire una funzione fooCurried come sopra che posso usare facilmente in contesti diversi ma mi consente di usare parametri con nome?

mi piacerebbe qualcosa che posso usare in questo modo:

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

Grazie in anticipo!

+2

Beh, io direi che è l'applicazione parziale non currying. Se volessi che fosse al curry, lo definiresti come ad es. 'def foo (a: String) (b: String, c: String, d: String) = ???'. –

+0

@MateuszKubuszok Sì, mi dispiace per aver usato la terminologia errata. In questo caso non controllo 'foo', quindi non posso cambiarlo usando il formato che hai suggerito. Potrei fare un wrapper però. – rmin

risposta

4

ne dite di questo:

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

è possibile utilizzarlo in questo modo:

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

Questo evita anche una costosa classe anonima – Clashsoft

+0

@Clashsoft Puoi approfondire cosa intendi evitando una costosa classe anonima? – rmin

1

Un modo alternativo in cui è possibile sta usando case class:

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

Ma allora il vostro foo avrebbe preso una classe come argomento, invece di 4 stringhe multiple.