gpt4 book ai didi

scala - Scala中的自定义 "let"表达式

转载 作者:行者123 更新时间:2023-12-04 23:03:00 27 4
gpt4 key购买 nike

我很想拥有let构造类似于 Scala 中的 Haskell 中的构造。我尝试了几种方法,但似乎没有一个是好的。这是一些代码:

object CustomLet extends App {
val data = for (i <- 1 to 1024; j <- 1 to 512) yield (i % j) * i * (i + 1) - 1

def heavyCalc() = { println("heavyCalc called"); data.sum }

def doSomethingWithRes(res: Int) = {
println(s"${res * res}")
1
}

def cond(value: Int): Boolean = value > 256

// not really usable, even though it's an expression (2x heavyCalc calls)
def withoutLet() = if (cond(heavyCalc())) doSomethingWithRes(heavyCalc()) else 0

// not an expression
def letWithVal(): Int = {
val res = heavyCalc()
if (cond(res)) doSomethingWithRes(res)
else 0
}

// a lot of code to simulate "let", at least it is an expression
def letWithMatch(): Int = heavyCalc() match {
case res => if (cond(res)) doSomethingWithRes(res) else 0
}

// not perfect solution from
// http://stackoverflow.com/questions/3241101/with-statement-equivalent-for-scala/3241249#3241249
def let[A, B](param: A)(body: A => B): B = body(param)

// not bad, but I'm not sure if it could handle more bindings at once
def letWithApp(): Int = let(heavyCalc()) {res => if (cond(res)) doSomethingWithRes(res) else 0}

List[(String, () => Int)](
("withoutLet", withoutLet),
("letWithVal", letWithVal),
("letWithMatch", letWithMatch),
("letWithApp", letWithApp)
).foreach(
item => item match {
case (title, func) => {
println(s"executing $title")
val ret = func()
println(s"$title finished with $ret")
println()
}
}
)
}

这是它的理想外观(只有一个绑定(bind),更多可以用 , 分隔;不确定 in 关键字):

  // desired look
def letTest(): Int =
let res = heavyCalc() in
if (cond(res)) doSomethingWithRes(res) else 0

我不确定这是否可能,但我没有使用大多数高级 Scala 东西(如宏)的经验,所以我无法确定。

EDIT1:需要明确的是,我对它的主要期望是:成为 表达式 和相对 简单语法 (就像上面概述的那样)。

最佳答案

您可以使用正向管道:

object ForwardPipeContainer {
implicit class ForwardPipe[A](val value: A) extends AnyVal {
def |>[B](f: A => B): B = f(value)
}
}

像这样使用:
import ForwardPipeContainer._

def f(i: Int) = i * i

println( f(3) |> (x => x * x) )

您可以将多个参数放在一个元组中:
println( (f(2), f(3)) |> (x => x._1 * x._2) )

如果与部分函数 synatx 结合使用,效果会更好:
println( (f(2), f(3)) |> { case (x, y) => x * y } )

这个答案是 What is a good way of reusing function result in Scala 的变体, 两者都基于 Cache an intermediate variable in an one-liner我从哪里得到最初的想法。

关于scala - Scala中的自定义 "let"表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18417105/

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