简体   繁体   English

了解Scala Implicits

[英]Understanding Scala Implicits

While reading Functional Programming in Scala by Chiusano and Bjarnason, I encountered the following code in chapter 9, Parser Combinators: 在阅读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)
  }
}

I understand that if there is a type incompatibility or missing parameters during compilation, the Scala compiler would look for a missing function that converts the non-matching type to the desired type or a variable in scope with the desired type that fits the missing parameter respectively. 我理解,如果在编译期间存在类型不兼容或缺少参数,Scala编译器将查找缺少的函数,该函数将非匹配类型转换为所需类型或范围内的变量,分别具有适合缺失参数的所需类型。

If a string occurs in a place that requires a Parser[String] , the string function in the above trait should be invoked to convert the string to a Parser[String] . 如果字符串出现在需要Parser[String] ,则应调用上述特征中的字符串函数将字符串转换为Parser[String]

However, I've difficulties understanding the operators and asStringParser functions. 但是,我很难理解operatorsasStringParser函数。 These are the questions that I have: 这些是我的问题:

  1. For the implicit operators function, why isn't there a return type? 对于隐式运算符函数,为什么不存在返回类型?
  2. Why is ParserOps defined as a case class and why can't the | 为什么ParserOps定义为一个case class ,为什么不能| or or function be defined in the Parsers trait itself? 或者在Parsers特征本身中定义or函数?
  3. What exactly is the asStringParser trying to accomplish? asStringParser想要完成什么? What is its purpose here? 它的目的是什么?
  4. Why is self needed? 为什么需要self The book says, "Use self to explicitly disambiguate reference to the or method on the trait," but what does it mean? 这本书说,“使用self来明确消除对特征或方法的引用的歧义”,但这是什么意思?

I'm truly enjoying the book but the use of advanced language-specific constructs in this chapter is hindering my progress. 我真的很喜欢这本书,但本章中使用高级语言特定的结构阻碍了我的进步。 It would be of great help if you can explain to me how this code works. 如果你能向我解释这段代码是如何工作的,那将会很有帮助。 I understand that the goal is to make the library "nicer" to use through operators like | 据我所知,目标是让库“更好”通过像|运营商使用 and or , but don't understand how this is done. or ,但不明白这是怎么做的。

  1. Every method has a return type. 每个方法都有一个返回类型。 In this case, it's ParserOps[A] . 在这种情况下,它是ParserOps[A] You don't have to write it out explicitly, because in this case it can be inferred automatically. 您不必明确地将其写出来,因为在这种情况下可以自动推断出来。
  2. Probably because of the automatically provided ParserOps.apply -factory method in the companion object. 可能是因为伴随对象中自动提供的ParserOps.apply -factory方法。 You need fewer val s in the constructor, and you don't need the new keyword to instantiate ParserOps . 在构造函数中需要更少的val ,并且您不需要new关键字来实例化ParserOps It is not used in pattern matching though, so, you could do the same thing with an ordinary (non- case ) class, wouldn't matter. 虽然它不用于模式匹配,所以,你可以用普通(非case )类做同样的事情,无关紧要。
  3. It's the "pimp-my-library"-pattern. 这是“pimp-my-library” - 模式。 It attaches methods | 它附加方法| and or to Parser , without forcing Parser to inherit from anything. 和/ or Parser ,没有强迫Parser继承任何东西。 In this way, you can later declare Parser to be something like ParserState => Result[A] , but you will still have methods | 通过这种方式,您可以稍后声明Parser是像ParserState => Result[A]但你仍然有方法| and or available (even though Function1[ParserState, Result[A]] does not have them). 和/ or可用(即使Function1[ParserState, Result[A]]没有它们)。
  4. You could put | 你可以把| and or directly in Parsers , but then you would have to use the syntax or直接在Parsers ,但是你必须使用语法

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

    instead of the much nicer 而不是更好

     a | b a or b 

There are no "real operators" in Scala, everything is a method. Scala中没有“真正的运算符”,一切都是方法。 If you want to implement a method that behaves as if it were an infix operator, you do exactly what is done in the book. 如果您想要实现一个行为就像它是一个中缀运算符的方法,那么您可以完成本书中的操作。

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

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