加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中自定义“let”表达式

发布时间:2020-12-16 09:53:23 所属栏目:安全 来源:网络整理
导读:我很乐意让我们构建类似于 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("h
我很乐意让我们构建类似于 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
  // https://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()
      }
    }
  )
}

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

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

我不确定它是否可能,但我没有大多数高级Scala之类的东西,比如宏,所以我无法分辨.

编辑1:要清楚,我期待的主要内容是:表达和相对简单的语法(如上所述).

解决方法

你可以使用前进管道:

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,我得到了最初的想法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读