因此,在使用Scala解析器时,可能有:
case class MyParser(foos: List[String]) extends Parsers {
val bars: List[Parser[String]] = foos.map(parserFromString)
// Expensive function
def parserFromString(s: String): Parser[String] = ???
}Parser是一个依赖于路径的类型,因此不能重构此代码,以便可以从构造函数传入bars。请注意,在我的用例中,parserFromString实际上创建了一个MyParser,使得MyParser构造变成了O(N!)在哪里N = foos.size。
因此,假设现在我希望通过另一个bars添加到foo。FP的方法是重构,将bars包含在构造函数中,然后定义类似于def +(foo: String): MyParser = copy(bars = bars :+ parserFromString(foo)的内容,但正如前面提到的,我不能从头开始重新创建。
我的解决方案就是让bars成为一个private var,并使用Unit方法update (即def update(foo: String): Unit = bars +:= parserFromString(foo) )对其进行变异。
我的第一个问题很简单:我被困住了吗?我一定要用突变吗?
第二个问题: Parboiled2是否遭受了这种痛苦?它们是否使用路径依赖类型(乍一看不像),如果是的话,Scala解析器为什么使用路径依赖类型?
如果parboiled2不受路径依赖类型的影响,这本身就可能是使用它的一个理由!
如果有人想知道为什么我需要从参数创建Parser__s,那是因为我正在实现一种语言,用户可以在这种语言中定义宏并使用这些宏来定义其他宏。所以不,在别人告诉我改变设计之前,我不能。我也不想变,因为我以后需要多线程。
发布于 2015-03-29 08:55:11
Parser是一个依赖于路径的类型,因此不能重构此代码,以便可以从构造函数传入条形图。
是的,它可以:
// could also be trait and mixed in where you need it
object MyParsers extends Parsers {
case class MyParser(bars: List[Parser[String]]) {
def +(foo: String): MyParser = copy(bars = bars :+ parserFromString(foo))
...
}
}Parboiled2会因此而受苦吗?他们是否使用依赖于路径的类型(乍一看不像)?
不,你可以从示例上看到。
如果是这样的话,为什么Scala解析器使用路径依赖类型?
正如上面所示,这不应该是一个问题。在某些情况下,我遇到了路径依赖类型的麻烦,但没有使用解析器。
对于Scala-解析器和par需氧机之间的选择,我个人会更多地考虑性能,您喜欢的DSL,等等。上一次我看了parboiled,它没有真正的方法来影响错误报告,但是这个现在是固定的。
https://stackoverflow.com/questions/29326396
复制相似问题