passing on default parameter in scala?
-
25-06-2021 - |
Frage
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?
Lösung
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
Andere Tipps
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]
.