[英]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. 但是,我很难理解
operators
和asStringParser
函数。 These are the questions that I have: 这些是我的问题:
case class
and why can't the |
case class
,为什么不能|
or or
function be defined in the Parsers trait itself? or
函数? asStringParser
trying to accomplish? asStringParser
想要完成什么? What is its purpose here? self
needed? self
? The book says, "Use self to explicitly disambiguate reference to the or method on the trait," but what does it mean? 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
,但不明白这是怎么做的。
ParserOps[A]
. ParserOps[A]
。 You don't have to write it out explicitly, because in this case it can be inferred automatically. 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
)类做同样的事情,无关紧要。 |
|
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]]
没有它们)。 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.