Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 什么是地图/平面地图功能用于理解?_Scala_Flatmap - Fatal编程技术网

Scala 什么是地图/平面地图功能用于理解?

Scala 什么是地图/平面地图功能用于理解?,scala,flatmap,Scala,Flatmap,我想看看在map/flatmap中传递的f函数,但运气不好。我抛出了一个异常,以查看f的任何迹象,但该异常不起作用。这个函数是什么?它是如何在幕后生成的 Exception in thread "main" java.lang.RuntimeException at x.x.Main$A.getInt(Empty.scala:8) at x.x.Main$A.flatMap(Empty.scala:10) object Main extends App { class A {

我想看看在map/flatmap中传递的
f
函数,但运气不好。我抛出了一个异常,以查看
f
的任何迹象,但该异常不起作用。这个函数是什么?它是如何在幕后生成的

Exception in thread "main" java.lang.RuntimeException
   at x.x.Main$A.getInt(Empty.scala:8)
   at x.x.Main$A.flatMap(Empty.scala:10)

object Main extends App {

  class A {
    def getInt: Int = throw new RuntimeException
    def map(f: Int => Boolean): Boolean = f(getInt)
    def flatMap(f: Int => Boolean): Boolean = f(getInt)
  }

  for {
    x <- new A
    y <- new A
  } yield x == y
}
线程“main”java.lang.RuntimeException中的异常 在x.x.Main$A.getInt处(空的.scala:8) 在x.x.Main$A.flatMap(空的.scala:10) 对象主应用程序{ 甲级{ def getInt:Int=抛出新的RuntimeException def映射(f:Int=>Boolean):Boolean=f(getInt) def flatMap(f:Int=>Boolean):Boolean=f(getInt) } 为了{
x用于您理解的等效代码

for {
  x <- new A
  y <- new A
} yield x == y
您可以使用
scalac-Xprint:parser main.scala
生成代码,以便理解

new A().flatMap(((x) => new A().map(((y) => x.$eq$eq(y)))))
您也可以在REPL中获得它,而无需添加如下宏:

new A().flatMap{ x => new A().map{ y => x == y } }
import reflect.runtime.universe._

show{ reify{
  for {
    x <- new A
    y <- new A
  } yield x == y
}.tree }
// new $read.A().flatMap(((x) => new $read.A().map(((y) => x.$eq$eq(y)))))
import reflect.runtime.universe_
显示{具体化{
为了{
x.$eq$eq(y(()()))

如果您使用的是Scala 2.10或更高版本,您可以使用以下命令在repl中显示已卸载的Scala代码:

import scala.reflect.macros.Context // use BlackboxContext if you're in 2.11
import scala.reflect.runtime.universe._
import scala.language.experimental.macros

def _desugar(c : Context)(expr : c.Expr[Any]): c.Expr[Unit] = {
  import c.universe._
  println(show(expr.tree))
  reify {}
}

def desugar(expr : Any): Unit = macro _desugar
scala> class A {
     |   def getInt: Int = throw new RuntimeException
     |   def map(f: Int => Boolean): Boolean = f(getInt)
     |   def flatMap(f: Int => Boolean): Boolean = f(getInt)
     | }
defined class A

scala> desugar {
     |   for {
     |     x <- new A
     |     y <- new A
     |   } yield x == y
     | }
new $line15.$read.$iw.$iw.$iw.$iw.A().flatMap(((x: Int) => new $line15.$read.$iw.$iw.$iw.$iw.A().map(((y: Int) => x.==(y)))))
这将允许您传入代码块,并查看它们转换为什么。例如,在repl中:

import scala.reflect.macros.Context // use BlackboxContext if you're in 2.11
import scala.reflect.runtime.universe._
import scala.language.experimental.macros

def _desugar(c : Context)(expr : c.Expr[Any]): c.Expr[Unit] = {
  import c.universe._
  println(show(expr.tree))
  reify {}
}

def desugar(expr : Any): Unit = macro _desugar
scala> class A {
     |   def getInt: Int = throw new RuntimeException
     |   def map(f: Int => Boolean): Boolean = f(getInt)
     |   def flatMap(f: Int => Boolean): Boolean = f(getInt)
     | }
defined class A

scala> desugar {
     |   for {
     |     x <- new A
     |     y <- new A
     |   } yield x == y
     | }
new $line15.$read.$iw.$iw.$iw.$iw.A().flatMap(((x: Int) => new $line15.$read.$iw.$iw.$iw.$iw.A().map(((y: Int) => x.==(y)))))
这适用于大多数任何表达式,并允许您检查编译期间实际代码将转换为什么

更新
我应该指出我的源代码-我的
desugar
版本是在github上的repo中找到的一个函数的稍微修改版本。

@TravisBrown:谢谢你,修复了。我应该休息一下。+1用于简洁、直接的回答(与我的相比)和-Xprint的引用。更简单:
scala>reflect.runtime.universe.reify{for(x x))(List.canBuildFrom))
这是一个非常棒(而且完全出乎意料)的答案-10/10看起来塞尼亚在repl中有一个比我更好的解决方案来去除糖渍。也许你应该接受他们的答案而不是我的答案。