假设我需要懒惰地阅读XML。我正在使用XMLEventReader返回stream
的{{1}}(懒惰列表)。我想解析此流,以便将其转换为某些域对象的流。
例如,我想将XML <xs><x><s>aaa</s></x><x><s>bbb</s></x><x><s>ccc</s></x></xs>
转换为case class X(s: String)
我想使用parser combinators
。我可以将XMLEvents
的输入流的解析器定义为函数Stream[XMLEvent] => Option[(A, Stream[XMLEvent])]
的包装类,其中包含map
和flatMap
:
import scala.xml.pull._
type Events = Stream[XMLEvent]
type Result[A] = Option[(A, Events)]
class Parser[A](run: Events => Result[A]) {
def apply(es: Events) = run(es)
def map[B](f: A => B): Parser[B] = new Parser (
es => this(es) map {case (a, rest) => (f(a), rest)}
)
def flatMap[B](f: A => Parser[B]): Parser[B] = new Parser (
es => this(es) flatMap {case (a, rest) => f(a)(rest)}
)
}
有意义吗?我如何重用标准XMLEvents库,而不是像上面那样编写自己的class Parser[A](run: Events => Result[A])
?