gpt4 book ai didi

Scala函数式编程体操

转载 作者:行者123 更新时间:2023-12-04 02:30:42 29 4
gpt4 key购买 nike

我正在尝试以尽可能少的代码和尽可能在功能上执行以下操作:

def restrict(floor : Option[Double], cap : Option[Double], amt : Double) : Double

显然,以下工作:
= (floor -> cap) match {
case (None, None) => amt
case (Some(f), None) => f max amt
case (None, Some(c)) => c min amt
case (Some(f), Some(c)) => (f max amt) min c
}

我真的希望有更优雅的东西,并且会接受使用 Scalaz 图书馆!您可以假设以下情况为真:
floor.forall( f => cap.forall( _ > f))

如果有人感兴趣,这里是一些测试代码 :
object Comparisons {
sealed trait Cf {
def restrict(floor: Option[Double], cap: Option[Double], amt: Double): Double
}

def main(args: Array[String]) {
val cf : Cf = //TODO - your impl here!
def runtest(floor: Option[Double], cap: Option[Double], amt: Double, exp : Double) : Unit = {
val ans = cf.restrict(floor, cap, amt)
println("floor=%s, cap=%s, amt=%s === %s (%s) : %s".format(floor, cap, amt, ans, exp, if (ans == exp) "PASSED" else "FAILED"))
}
runtest(Some(3), Some(5), 2, 3)
runtest(Some(3), Some(5), 3, 3)
runtest(Some(3), Some(5), 4, 4)
runtest(Some(3), Some(5), 5, 5)
runtest(Some(3), Some(5), 6, 5)

runtest(Some(3), None, 2, 3)
runtest(Some(3), None, 3, 3)
runtest(Some(3), None, 4, 4)
runtest(Some(3), None, 5, 5)
runtest(Some(3), None, 6, 6)

runtest(None, Some(5), 2, 2)
runtest(None, Some(5), 3, 3)
runtest(None, Some(5), 4, 4)
runtest(None, Some(5), 5, 5)
runtest(None, Some(5), 6, 5)

runtest(None, None, 2, 2)
runtest(None, None, 3, 3)
runtest(None, None, 4, 4)
runtest(None, None, 5, 5)
runtest(None, None, 6, 6)
}
}

最佳答案

编辑 2 :

一边想着cataX方法,我发现cataX无非是简单的折叠。使用它,我们可以获得一个纯 Scala 解决方案,而无需任何额外的库。

所以,这里是:

( (amt /: floor)(_ max _) /: cap)(_ min _)

这与
cap.foldLeft( floor.foldLeft(amt)(_ max _) )(_ min _)

(并不是说这一定更容易理解)。

我认为你不能拥有比这更短的时间。

无论好坏,我们也可以使用 scalaz 解决它:
floor.map(amt max).getOrElse(amt) |> (m => cap.map(m min).getOrElse(m))

甚至:
floor.cata(amt max, amt) |> (m => cap.cata(m min, m))

作为一名“普通”Scala 程序员,您可能不知道所使用的特殊 Scalaz 运算符和方法( |>Option.cata)。它们的工作方式如下:
value |> function转换为 function(value)因此 amt |> (m => v fun m)等于 v fun amt .
opt.cata(fun, v)翻译成
opt match {
case Some(value) => fun(value)
case None => v
}

opt.map(fun).getOrElse(v) .

参见 cata 的 Scalaz 定义和 |> .

更对称的解决方案是:
amt |> (m => floor.cata(m max, m)) |> (m => cap.cata(m min, m))

编辑:抱歉,现在变得很奇怪,但我也想要一个免积分版本。新款 cataX是 curry 。第一个参数采用二元函数;第二个是值(value)。
class CataOption[T](o: Option[T]) {
def cataX(fun: ((T, T) => T))(v: T) = o.cata(m => fun(m, v), v)
}
implicit def option2CataOption[T](o: Option[T]) = new CataOption[T](o)

o匹配 Some我们返回值为 o 的函数并且应用第二个参数,如果 o匹配 None我们只返回第二个参数。

现在我们开始:
amt |> floor.cataX(_ max _) |> cap.cataX(_ min _)

也许他们已经在 Scalaz 有了这个……?

关于Scala函数式编程体操,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4145196/

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