Question

Please consider the following example

def foo(a: Int, b: Int = 100) = a + b
def bar(a: Int, b: Int = 100) = foo(a, b) * 2

This works, but note I have to supply the same default value to b in both functions. My intention is actually the following

def bar(a: Int, b: Int) = foo(a, b) * 2
def bar(a: Int)    = foo(a) * 2

But this becomes cumbersome when you have more optional arguments, and additional functions in the chain (such as baz that invokes bar in the same manner). Is there a more concise way to express this in scala?

Was it helpful?

Solution

I don't think there is; if you compose foo with a doubling function:

val bar = (foo _).curried((_: Int)) andThen ((_: Int) *2)
// (please, please let there be a simpler way to do this...)

you lose the default arguments, because function objects don't have them.

If it's worth it in your use-case, you could create a case class containing your arguments which you pass instead of multiple individual ones, e.g.

case class Args(a: Int, b: Int = 100, c: Int = 42, d: Int = 69)
def foo(args: Args) = { import args._; a + b + c + d }
def bar(args: Args) = foo(args) * 2

OTHER TIPS

I would suggest to use Option.

def bar(a: Int, b: Option[Int] = None) = b match {
  case Some(x) => foo(a,x) * 2
  case _ => foo(a) * 2
}

This will exactly do what you want. Another way would be using varargs.

def baz(a: Int)(b: Int*) = b.headOption match {
  case Some(x) => foo(a,x) * 2
  case _ => foo(a) * 2
}

I would prefer the first way, because it is obvious, that the parameter is optional. The second solution was not to deal with the wrapping in an Option, but it is not clear by the signature, that only the first element of the collection will be considered. baz(1)(2) == baz(1)(2,3,4,5) is true.

Edit

To make the one with the Option look like your desired calls, you might use implicits.

implicit def int2Some(i: Int) = Some(i)

Now you can call the function the following:

bar(1,2)
bar(1,Some(2))
bar(1)
bar(1,None)

The implicit is called automatically where ever it is usefull. But your users might get confused, why the function can be called with an Int instead of an Option[Int].

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top