gpt4 book ai didi

scala currying/partials 构建函数过滤器列表

转载 作者:行者123 更新时间:2023-12-02 05:14:19 35 4
gpt4 key购买 nike

给定以下代码:

case class Config(
addThree: Boolean = true,
halve: Boolean = true,
timesFive: Boolean = true
)


def doOps(num: Integer, config: Config): Integer = {
var result: Integer = num
if ( config.addThree ) {
result += 3
}
if ( config.halve ) {
result /= 2
}
if ( config.timesFive ) {
result *= 5
}
result
}

val config = Config(true,false,true)

println( doOps(20, config) )
println( doOps(10, config) )

我想用更高效和惯用的构造替换丑陋的 doOps 方法。具体来说,我想构建一个函数链,根据所使用的特定配置仅执行所需的转换。我知道我可能想创建某种部分应用的函数,我可以将 Integer 传递给它,但我对如何以有效的方式实现这一点一无所知。

我特别想避免 doOps 中的 if 语句,我希望生成的结构只是一个函数链,调用链中的下一个函数而不先检查条件。

生成的代码,我想应该是这样的:

case class Config(
addThree: Boolean = true,
halve: Boolean = true,
timesFive: Boolean = true
)

def buildDoOps(config: Config) = ???

val config = Config(true,false,true)
def doOps1 = buildDoOps(config)

println( doOps1(20) )
println( doOps1(10) )

最佳答案

这是我的建议。基本上我创建了一系列相互独立的函数。如果其中一项操作被禁用,我会将其替换为 identity。最后,我使用 num 参数作为初始值 foldLeft 处理该序列:

case class Config(
addThree: Boolean = true,
halve: Boolean = true,
timesFive: Boolean = true
) {

private val funChain = Seq[Int => Int](
if(addThree) _ + 3 else identity _,
if(halve) _ / 2 else identity _,
if(timesFive) _ * 5 else identity _
)

def doOps(num: Int) = funChain.foldLeft(num){(acc, f) => f(acc)}

}

我将 doOps() 放在 Config 中,因为它很适合那里。

Config(true, false, true).doOps(10)  //(10 + 3 ) * 5 = 65

如果你是受虐狂,foldLeft()可以这样写:

def doOps(num: Int) = (num /: funChain){(acc, f) => f(acc)}

如果你不喜欢identity,使用Option[Int => Int]flatten:

private val funChain = Seq[Option[Int => Int]](
if(addThree) Some(_ + 3) else None,
if(halve) Some(_ / 2) else None,
if(timesFive) Some(_ * 5) else None
).flatten

关于scala currying/partials 构建函数过滤器列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14900305/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com