在 Scala 中,如何定义一个带有元组参数的函数变量
In Scala, how to define a variable that is a function with a tuple argument
在 Scala class 中,objective 是实现一个 Builder 模式,构造的 class 的参数之一是一个函数,它接受一个元组和 returns一个双。
在生成器 class 中,需要一个变量 tupleFunc
来保存具有默认实现的此类函数。 Builder 还将有一个方法 tupleFuncIs
来覆盖默认值。
class FunctionProblem private (val tupleFunc: (Boolean, Double, Int) => Double,
val func: Double => Double) {
}
object FunctionProblem {
class Builder {
// problem line follows
private var tupleFunc: ((Boolean, Double, Int) => Double) = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble
private var func: (Double => Double) = (x: Double) => 0.75 * x
def tupleFuncIs(x: (Boolean, Double, Int) => Double): Builder = { tupleFunc = x; this }
def funcIs(x: Double => Double): Builder = { func = x; this }
def build(): FunctionProblem = new FunctionProblem(tupleFunc, func)
}
def builder(): Builder = new Builder
}
但是,Scala 编译器抱怨类型不匹配
[ant:scalac] found : ((Boolean, Double, Int)) => Double
[ant:scalac] required: (Boolean, Double, Int) => Double
[ant:scalac] private var tupleFunc: ((Boolean, Double, Int) => Double) = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble
[ant:scalac] ^
为什么会发现双括号,或者更好的是,应该如何重写tupleFunc
以满足编译器?
你需要更多parens
class FunctionProblem private (val tupleFunc: ((Boolean, Double, Int)) => Double,
val func: Double => Double) {
}
object FunctionProblem {
class Builder {
// problem line follows
private var tupleFunc: ((Boolean, Double, Int)) => Double = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble
private var func: (Double => Double) = (x: Double) => 0.75 * x
def tupleFuncIs(x: ((Boolean, Double, Int)) => Double): Builder = { tupleFunc = x; this }
def funcIs(x: Double => Double): Builder = { func = x; this }
def build(): FunctionProblem = new FunctionProblem(tupleFunc, func)
}
def builder(): Builder = new Builder
}
请输入您的类型
((Boolean, Double, Int) => Double)
只是一个接受 3 个参数而不是元组的函数,对于元组,你需要将它包装在另一个 ()
中,如下所示:
(((Boolean, Double, Int)) => Double)
顺便说一句,尽管您的代码中到处都是函数,但功能不是很好,它看起来很像 java。您也许应该考虑使用不可变值和 return 新构建器进行中间化。
我建议以更多的 scala 方式实现此任务是使用 case class
import FunctionProblem._
case class FunctionProblem(tupleFunc: TupleFunc = defaultTupleFunc, func: DoubleFunc = defaultDoubleFunc)
object FunctionProblem {
type TupleFunc = ((Boolean, Double, Int)) => Double
type DoubleFunc = Double => Double
private val defaultTupleFunc: TupleFunc = x => if (x._1) x._2 else x._3.toDouble
private val defaultDoubleFunc: DoubleFunc = 0.75 * _
}
FunctionProblem().func(3) //res0: Double = 2.25
FunctionProblem(func = _ + 5).func(3) //res1: Double = 8.0
FunctionProblem(tupleFunc = _ => 32).tupleFunc((true, 5, 1)) //res2: Double = 32.0
如果您想链式调用,可以使用自动生成的 copy
方法
FunctionProblem().copy(func = _ + 9).copy(tupleFunc = _ => 3).func(1) //res3: Double = 10.0
在 Scala class 中,objective 是实现一个 Builder 模式,构造的 class 的参数之一是一个函数,它接受一个元组和 returns一个双。
在生成器 class 中,需要一个变量 tupleFunc
来保存具有默认实现的此类函数。 Builder 还将有一个方法 tupleFuncIs
来覆盖默认值。
class FunctionProblem private (val tupleFunc: (Boolean, Double, Int) => Double,
val func: Double => Double) {
}
object FunctionProblem {
class Builder {
// problem line follows
private var tupleFunc: ((Boolean, Double, Int) => Double) = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble
private var func: (Double => Double) = (x: Double) => 0.75 * x
def tupleFuncIs(x: (Boolean, Double, Int) => Double): Builder = { tupleFunc = x; this }
def funcIs(x: Double => Double): Builder = { func = x; this }
def build(): FunctionProblem = new FunctionProblem(tupleFunc, func)
}
def builder(): Builder = new Builder
}
但是,Scala 编译器抱怨类型不匹配
[ant:scalac] found : ((Boolean, Double, Int)) => Double
[ant:scalac] required: (Boolean, Double, Int) => Double
[ant:scalac] private var tupleFunc: ((Boolean, Double, Int) => Double) = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble
[ant:scalac] ^
为什么会发现双括号,或者更好的是,应该如何重写tupleFunc
以满足编译器?
你需要更多parens
class FunctionProblem private (val tupleFunc: ((Boolean, Double, Int)) => Double,
val func: Double => Double) {
}
object FunctionProblem {
class Builder {
// problem line follows
private var tupleFunc: ((Boolean, Double, Int)) => Double = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble
private var func: (Double => Double) = (x: Double) => 0.75 * x
def tupleFuncIs(x: ((Boolean, Double, Int)) => Double): Builder = { tupleFunc = x; this }
def funcIs(x: Double => Double): Builder = { func = x; this }
def build(): FunctionProblem = new FunctionProblem(tupleFunc, func)
}
def builder(): Builder = new Builder
}
请输入您的类型
((Boolean, Double, Int) => Double)
只是一个接受 3 个参数而不是元组的函数,对于元组,你需要将它包装在另一个 ()
中,如下所示:
(((Boolean, Double, Int)) => Double)
顺便说一句,尽管您的代码中到处都是函数,但功能不是很好,它看起来很像 java。您也许应该考虑使用不可变值和 return 新构建器进行中间化。
我建议以更多的 scala 方式实现此任务是使用 case class
import FunctionProblem._
case class FunctionProblem(tupleFunc: TupleFunc = defaultTupleFunc, func: DoubleFunc = defaultDoubleFunc)
object FunctionProblem {
type TupleFunc = ((Boolean, Double, Int)) => Double
type DoubleFunc = Double => Double
private val defaultTupleFunc: TupleFunc = x => if (x._1) x._2 else x._3.toDouble
private val defaultDoubleFunc: DoubleFunc = 0.75 * _
}
FunctionProblem().func(3) //res0: Double = 2.25
FunctionProblem(func = _ + 5).func(3) //res1: Double = 8.0
FunctionProblem(tupleFunc = _ => 32).tupleFunc((true, 5, 1)) //res2: Double = 32.0
如果您想链式调用,可以使用自动生成的 copy
方法
FunctionProblem().copy(func = _ + 9).copy(tupleFunc = _ => 3).func(1) //res3: Double = 10.0