7

I have a method with 4 parameters that gets used in blocks. Within each block, the first parameter is always the same:

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

I want a quick way to create a method for each block so that I only need to specify the other 3 parameters. Currently I can do this:

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

The problem with this approach is that I lose my named parameters. They become v1, v2 and v3. Using named parameters is important in this case because the types of the other 3 parameters are the same and so are easy to mix up.

Is there a clean way to define a fooCurried function like above which I can use easily in different contexts but lets me used named parameters?

I'd like something I can use like this:

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

Thanks in advance!

2
  • 2
    Well, I'd say it's partial application not currying. If you wanted it to be curried you would define it as e.g. def foo(a: String)(b: String, c: String, d: String) = ???. Commented Jan 21, 2016 at 11:35
  • @MateuszKubuszok Yes sorry for using incorrect terminology. In this case I don't control foo so I can't change it using the format you suggested. I could make a wrapper though. Commented Feb 1, 2016 at 23:48

3 Answers 3

4

How about this :

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

You can use it like this :

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 
Sign up to request clarification or add additional context in comments.

2 Comments

This also avoids a costly anonymous class
@Clashsoft Can you elaborate on what you mean by avoiding a costly anonymous class?
1

One alternative way where you can is using 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")) 

But then your foo would take a class as argument instead of 4 multiple strings.

Comments

0

You can wrap all b c d in a case class like the following

case class FooExtraParams(b: String, c: String, d: String) def foo(a: String)(params: FooExtraParams) val fooA = foo(a = "a") _ fooA(FooExtraParams(b="B", c="C", d="D")) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.