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

标签 scala functional-programming parser-combinators

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

代码片段:

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`
  }

  .....
}

最佳答案

在您引用的代码中,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)

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

关于Scala:为什么使用类型作为方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49683820/

相关文章:

compiler-construction - Scalas/Haskells 解析器组合器是否足够?

Scala,树结构数据的解析器组合器

java - 如何修改Scala代码让它停止计算?

java - 为什么 LocalDate 没有实现 Comparable<LocalDate>?

scala - 如何推理 Scala Cats/fs2 中的堆栈安全?

functional-programming - 如何将多个参数传入 Ramda 组合链?

functional-programming - 惰性序列中 "Lose your head"的解释

scala - 部署静态文件的方法是什么,以便 Spray 可以为它们提供服务?

scala - 在 Spark 中强制立即缓存的最有效方法是什么?

rust - 使用 nom 捕获整个连续的匹配输入