【问题标题】:Scala: why is a type used as a method call?Scala:为什么将类型用作方法调用?
【发布时间】:2018-04-06 10:02:44
【问题描述】:

Scala:为什么将类型用作方法调用?

我是 Scala 新手,正在阅读“Scala 中的函数式编程” 作者:PAUL CHIUSANO 和 RÚNAR BJARNASON。

我试图理解第 9 章中解析器组合器的源代码,但我被一个 问题:在源代码中,Parser[A] 被声明为一种类型,但我可以看到 Parser[A] 用作方法调用。

我的问题是:为什么类型的实例可以用作方法 打电话?

def or[A](p: Parser[A], p2: => Parser[A]): Parser[A] =
    s => p(s) match {   // ========> p is used as a method call.
      case Failure(e,false) => p2(s)
      case r => r // committed failure or success skips running `p2`
}

源代码链接:

https://github.com/fpinscala/fpinscala/blob/master/answers/src/main/scala/fpinscala/parsing

代码sn-p:

trait Parsers[Parser[+_]] { self => 
  .....
}


object ReferenceTypes {

  /** A parser is a kind of state action that can fail. */
  type Parser[+A] = ParseState => Result[A]

  case class ParseState(loc: Location) {
    ......
  }

  sealed trait Result[+A] {
    ......
  }

  case class Success[+A](get: A, length: Int) extends Result[A]
  case class Failure(get: ParseError, isCommitted: Boolean) extends Result[Nothing]

}

object Reference extends Parsers[Parser] {

  ......

  def or[A](p: Parser[A], p2: => Parser[A]): Parser[A] =
    s => p(s) match {
      case Failure(e,false) => p2(s)
      case r => r // committed failure or success skips running `p2`
  }

  .....
}

【问题讨论】:

    标签: scala functional-programming parser-combinators


    【解决方案1】:

    在您引用的代码中,Parser[+A] 被显式声明为函数类型

    type Parser[+A] = ParseState => Result[A]
    

    因此,Parser[+A] 类型的值可以应用于ParseState 类型的值。将 X => Y 类型的函数 p 应用于 X 类型的值 s 的常用语法是

    p(s)
    

    所以,它只是普通的函数应用程序,甚至不是某些用户定义的类的一些花哨的重写apply 方法。


    方法调用通常如下所示:

    obj.methodName(argument)
    

    它需要一个调用该方法的对象。如果对象是this,或者您之前已经导入过,则可以省略此项

    import obj._
    

    这样这个对象的所有方法在当前范围内都是可用的。在所有其他情况下,您需要一个调用方法的接收对象。


    函数应用

    p(s)
    

    实际上脱糖成一个特殊的方法调用

    p.apply(s)
    

    但这是一个旁白,它与问题并不真正相关。

    【讨论】:

    • 感谢您的解释。这对我很有帮助。我在源代码中搜索,但找不到任何带有签名 ParseState => Result[A] 的方法调用。我错过了什么吗?任何提示表示赞赏。谢谢!
    • @CodingNow “带有签名的方法调用”是什么意思?方法有签名。方法调用只是返回值。
    • 很抱歉给您带来了困惑。请允许我改写一下:我在源代码中进行了搜索,但找不到任何带有签名 ParseState => Result[A] 的方法定义
    • 再看this code。有一个类型别名:type Parser[+A] = ParseState => Result[A],即:Parser[A]isParseState => Result[A]完全相同。至少有 succeedorstringflatMapregexscope 等方法返回 Result[A]。整个类基本上除了定义一堆Parser[A](即ParseState => Result[A])类型的函数之外什么都不做。这些功能中的每一个都适用于p(s)
    • @CodingNow 是否令人困惑,或者是否 仍然令人困惑?我希望一旦您看到类型别名Parser[A] = (State => Result[A]),它应该会变得清晰吗?如果还有不清楚的地方,那你还有机会问……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 2017-10-31
    相关资源
    最近更新 更多