Reputation: 20169
In Scala, is there a way to specify that a function should have default parameter values declared?
For example, in the code below, is there a way to specify in the signature of indirectHelloName
that the provided function must provide a default value for the second parameter?
def helloName(name: String, greating: String = "hello"): Unit = {
println(s"$greating $name")
}
def indirectHelloName(name: String, function: (String,String) => Unit): Unit = {
if (name == "Ted") {
function(name, "Custom Greeting for Ted!")
} else {
function(name) //This would use the default value for the second argument.
}
}
Upvotes: 5
Views: 490
Reputation: 369526
In Scala, is there a way to specify that a function should have default parameter values declared?
For example, in the code below, is there a way to specify in the signature of
indirectHelloName
that the provided function must provide a default value for the second parameter?
A function cannot have an optional parameter with default argument, therefore there is no way to specify one:
val f = (a: Int, b: Int) => a + b
//⇒ f: (Int, Int) => Int = $$Lambda$1073/0x000000080070c840@6cd98a05
val g = (a: Int, b: Int = 5) => a + b
// <console>:1: error: ')' expected but '=' found.
// val g = (a: Int, b: Int = 5) => a + b
// ^
val h = new Function2[Int, Int, Int] {
override def apply(a: Int, b: Int) = a + b
}
//⇒ h: (Int, Int) => Int = <function2>
val i = new Function2[Int, Int, Int] {
override def apply(a: Int, b: Int = 5) = a + b
}
//⇒ i: (Int, Int) => Int{def apply$default$2: Int @scala.annotation.unchecked.uncheckedVariance} = <function2>
i(3, 5)
//⇒ res: Int = 8
i(3)
// <console>:13: error: not enough arguments for method apply: (v1: Int, v2: Int)Int in trait Function2.
// Unspecified value parameter v2.
// h(3)
// ^
Upvotes: 2
Reputation: 51271
One thing you could do is move the default value from the parameter list to inside the method.
def helloName(in :String*) :Unit =
println(in.lift(1).getOrElse("hello") + ", " + in.head)
def indirectHelloName(name: String, function: (String*) => Unit): Unit =
if (name == "Ted") function(name, "Custom Greeting")
else function(name) //use default
usage:
indirectHelloName("Ted", helloName) //Custom Greeting, Ted
indirectHelloName("Tam", helloName) //hello, Tam
Upvotes: 3
Reputation: 10213
I tried and come up with the below answer
def helloName(name: String, greeting: String = "hello"): Unit = {
println(s"$greeting $name")
}
val helloNameFn = (x: String, y :String) => println(x + y)
type fn = (String, String) => Unit
def indirectHelloName(name: String, function:fn = helloNameFn): Unit = {
if (name == "Ted") {
function(name, "Custom Greeting for Ted!")
} else {
helloName(name) //This would use the default value for the second argument.
}
}
helloNameFn("123", "123")
Please try and let me know your comments.
Upvotes: 0