繁体   English   中英

了解Scala Implicits

[英]Understanding Scala Implicits

在阅读Chiusano和Bjarnason的Scala函数式编程时 ,我在第9章Parser Combinators中遇到了以下代码:

trait Parsers[ParseError, Parser[+_]] { self =>
  ...
  def or[A](s1: Parser[A], s2: Parser[A]): Parser[A]
  implicit def string(s: String): Parser[String]
  implicit def operators[A](p: Parser[A]) = ParserOps[A](p)
  implicit def asStringParser[A](a: A)(implicit f: A => Parser[String]):
    ParserOps[String] = ParserOps(f(a))

  case class ParserOps[A](p: Parser[A]) {
    def |[B>:A](p2: Parser[B]): Parser[B] = self.or(p,p2)
    def or[B>:A](p2: => Parser[B]): Parser[B] = self.or(p,p2)
  }
}

我理解,如果在编译期间存在类型不兼容或缺少参数,Scala编译器将查找缺少的函数,该函数将非匹配类型转换为所需类型或范围内的变量,分别具有适合缺失参数的所需类型。

如果字符串出现在需要Parser[String] ,则应调用上述特征中的字符串函数将字符串转换为Parser[String]

但是,我很难理解operatorsasStringParser函数。 这些是我的问题:

  1. 对于隐式运算符函数,为什么不存在返回类型?
  2. 为什么ParserOps定义为一个case class ,为什么不能| 或者在Parsers特征本身中定义or函数?
  3. asStringParser想要完成什么? 它的目的是什么?
  4. 为什么需要self 这本书说,“使用self来明确消除对特征或方法的引用的歧义”,但这是什么意思?

我真的很喜欢这本书,但本章中使用高级语言特定的结构阻碍了我的进步。 如果你能向我解释这段代码是如何工作的,那将会很有帮助。 据我所知,目标是让库“更好”通过像|运营商使用 or ,但不明白这是怎么做的。

  1. 每个方法都有一个返回类型。 在这种情况下,它是ParserOps[A] 您不必明确地将其写出来,因为在这种情况下可以自动推断出来。
  2. 可能是因为伴随对象中自动提供的ParserOps.apply -factory方法。 在构造函数中需要更少的val ,并且您不需要new关键字来实例化ParserOps 虽然它不用于模式匹配,所以,你可以用普通(非case )类做同样的事情,无关紧要。
  3. 这是“pimp-my-library” - 模式。 它附加方法| 和/ or Parser ,没有强迫Parser继承任何东西。 通过这种方式,您可以稍后声明Parser是像ParserState => Result[A]但你仍然有方法| 和/ or可用(即使Function1[ParserState, Result[A]]没有它们)。
  4. 你可以把| or直接在Parsers ,但是你必须使用语法

     |(a, b) or(a, b) 

    而不是更好

     a | b a or b 

Scala中没有“真正的运算符”,一切都是方法。 如果您想要实现一个行为就像它是一个中缀运算符的方法,那么您可以完成本书中的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM