[英]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]
。
但是,我很难理解operators
和asStringParser
函数。 这些是我的问题:
case class
,为什么不能|
或者在Parsers特征本身中定义or
函数? asStringParser
想要完成什么? 它的目的是什么? self
? 这本书说,“使用self来明确消除对特征或方法的引用的歧义”,但这是什么意思? 我真的很喜欢这本书,但本章中使用高级语言特定的结构阻碍了我的进步。 如果你能向我解释这段代码是如何工作的,那将会很有帮助。 据我所知,目标是让库“更好”通过像|
运营商使用 和or
,但不明白这是怎么做的。
ParserOps[A]
。 您不必明确地将其写出来,因为在这种情况下可以自动推断出来。 ParserOps.apply
-factory方法。 在构造函数中需要更少的val
,并且您不需要new
关键字来实例化ParserOps
。 虽然它不用于模式匹配,所以,你可以用普通(非case
)类做同样的事情,无关紧要。 |
和/ or
Parser
,没有强迫Parser
继承任何东西。 通过这种方式,您可以稍后声明Parser
是像ParserState => Result[A]
但你仍然有方法|
和/ or
可用(即使Function1[ParserState, Result[A]]
没有它们)。 你可以把|
or
直接在Parsers
,但是你必须使用语法
|(a, b) or(a, b)
而不是更好
a | b a or b
Scala中没有“真正的运算符”,一切都是方法。 如果您想要实现一个行为就像它是一个中缀运算符的方法,那么您可以完成本书中的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.