如何将其理解为flatMap实现

时间:2014-11-06 11:58:41

标签: scala

我试图将其理解为flatMap / map实现,但我正在努力弄清楚如何:

def operationParser: Parser[(Operation, Int, Int)] = {
    for {
      n1 <- Parser.natural
      _ <- Parser.list(Parser.space)
      op <- Parser.operation
      _ <- Parser.list(Parser.space)
      n2 <- Parser.natural
    } yield (op, n1, n2)
  }

2 个答案:

答案 0 :(得分:4)

您可以使用-Xprint:parser的{​​{1}}命令行选项查看该版本的内容:

源代码

scalac

编译器命令和输出

object Main {
  trait Operation

  trait Parser[A] {
    def map[B](fn: A => B): Parser[B] = ???
    def flatMap[B](fn: A => Parser[B]): Parser[B] = ???
  }

  object Parser {
    def natural: Parser[Int] = ???
    def space: Parser[String] = ???
    def list[A](p: Parser[A]): Parser[A] = ???
    def operation: Parser[Operation] = ???
  }

  def operationParser: Parser[(Operation, Int, Int)] = {
    for {
      n1 <- Parser.natural
      _ <- Parser.list(Parser.space)
      op <- Parser.operation
      _ <- Parser.list(Parser.space)
      n2 <- Parser.natural
    } yield (op, n1, n2)
  }
}

经过一些格式化后,desugared版本看起来像这样:

$ scalac -Xprint:parser Main.scala 
[[syntax trees at end of                    parser]] // Main.scala
package <empty> {
  object Main extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    abstract trait Operation extends scala.AnyRef;
    abstract trait Parser[A] extends scala.AnyRef {
      def $init$() = {
        ()
      };
      def map[B](fn: _root_.scala.Function1[A, B]): Parser[B] = $qmark$qmark$qmark;
      def flatMap[B](fn: _root_.scala.Function1[A, Parser[B]]): Parser[B] = $qmark$qmark$qmark
    };
    object Parser extends scala.AnyRef {
      def <init>() = {
        super.<init>();
        ()
      };
      def natural: Parser[Int] = $qmark$qmark$qmark;
      def space: Parser[String] = $qmark$qmark$qmark;
      def list[A](p: Parser[A]): Parser[A] = $qmark$qmark$qmark;
      def operation: Parser[Operation] = $qmark$qmark$qmark
    };
    def operationParser: Parser[scala.Tuple3[Operation, Int, Int]] = Parser.natural.flatMap(((n1) => Parser.list(Parser.space).flatMap(((_) => Parser.operation.flatMap(((op) => Parser.list(Parser.space).flatMap(((_) => Parser.natural.map(((n2) => scala.Tuple3(op, n1, n2)))))))))))
  }
}

您可以使用以下命令查看可用的编译阶段列表:

def operationParser: Parser[scala.Tuple3[Operation, Int, Int]] =
  Parser.natural.flatMap(((n1) =>
    Parser.list(Parser.space).flatMap(((_) =>
      Parser.operation.flatMap(((op) =>
        Parser.list(Parser.space).flatMap(((_) =>
          Parser.natural.map(((n2) =>
            scala.Tuple3(op, n1, n2)))))))))))

答案 1 :(得分:1)

根据经验,所有<-都成为flatMap,但最后一个(在您的情况下为n2 < -Parser.natural),后者变为map。但你可以&#34;欺骗&#34;并让编译器通过以下方式为您完成:

 scalac -Xprint:parser YourClass.sca

它将显示编译器为了理解而去糖化的内容。