我试图编写一个基于字符串输入返回另一个函数的函数。我想我希望matchfun("X")
成为(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)
^
答案 0 :(得分:1)
当foo是&#34; X&#34;当foo为&#34; Y&#34;时,您返回Function2[Double,Double,Double]
返回Function1[Double,Double]
对象(anyref)是可用的最具体的常用超类型。更改您的代码,以便所有分支返回相同的类型(或至少是一个有用的常用超类型)。在返回函数的情况下,这意味着每个函数需要具有相同数量的参数。
答案 1 :(得分:0)
试试这个:
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
阅读有关函数类型继承的内容。
修改强>
处理评论中提到的案例:
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
答案 2 :(得分:0)
您返回接受不同输入的函数,因此在不知道需要哪些参数的情况下很难推送输入。因此,不要按下输入,而是让函数自行提取输入。
所以我们需要某种源对象,我们称之为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
答案 3 :(得分:0)
您的问题是您必须帮助编译器,并且“match”语句中的所有分支应返回相同的类型。您在第二种情况“Y”中破坏了这些约束,因为您返回的是函数Double=>Double
而不是函数(Double,Double)=>Double
。
帮助编译器
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
}
}