Reputation: 4762
I'm trying to write a function that returns another function based on a string input. I think I want matchfun("X")
to be a (Double, Double) => Double
:
def matchfun(foo: String) = {
foo match {
case "X" => (x: Double, y: Double) => x + y
case "Y" => (x: Double) => x + 2
case "Z" => (x: Double, y: Double) => x * y
}
}
matchfun("X")
matchfun("X")(1,2)
matchfun: (foo: String)Object
res116: Object = <function2>
<console>:173: error: Object does not take parameters
matchfun("X")(1,2)
^
Upvotes: 0
Views: 82
Reputation: 3696
Your problem is that you have to help the compiler, and all the branches in the "match" statement should return the same type. You break those constraints in the second case "Y", because you return a function Double=>Double
and not a function (Double,Double)=>Double
.
Help the compiler
def matchfun(foo: String):(Double,Double)=>Double = {
foo match{
case "X"=> (a,b)=> a+b
case "Y"=> (a,b)=> a+2
case "Z"=> (a,b)=> a*b
}
}
Upvotes: 0
Reputation: 2583
Try this:
trait A extends ((Int,Int) => Int) with (Int => Int)
class B extends A {
def apply(a: Int, b: Int) = a + b
def apply(a: Int) = a
}
val b = new B
b(1) // 1
b(2,3) // 5
Read about function type inheritance.
EDIT
to handle the case mentioned in the comment:
trait A extends ((Int,Int,String) => Int) with (Int => Int)
class B extends A {
override def apply(a:Int,b:Int,x:String) = x match {
case "add" => a+b
case "mul" => a*b
}
override def apply(x:Int) = x
}
val b = new B
b(1) // 1
b(1,2,"add") // 3
b(1,2,"mul") // 2
Upvotes: 0
Reputation: 2168
You return functions that accept different inputs, so it's hard to push the input without knowing what parameters are needed. So instead of pushing the input, let the function pull the input on its own.
So we need some sort of source object, let's call it Point:
case class Point(x: Double, y: Double)
def matchfun(foo: String)(point: Point) = {
foo match {
case "X" => point.x + point.y
case "Y" => point.x + 2
case "Z" => point.x * point.y
}
}
val point = Point(2, 5)
matchfun("X")(point) // 7.0
matchfun("Y")(point) // 4.0
matchfun("Z")(point) // 10.0
Upvotes: 0
Reputation: 8519
When foo is "X" your return a Function2[Double,Double,Double]
when foo is "Y" you return a Function1[Double,Double]
Object (anyref) is the most specific common supertype available. Change your code so that all branches return the same type (or at least a useful common supertype). In the case of returning functions that means you need to have the same number of parameters for each function.
Upvotes: 1