我有一个ConfigRule
特征,其中transform
方法为
trait ConfigRule {
final def transform(doc: Node): Node = { .....}
}
然后我ConfigTransformer
看起来像transform
方法
trait ConfigTransformer {
def transform(doc: Node, rules: Seq[ConfigRule]) = {
rules.reduceLeft((x, y) => x.transform(doc).andThen(y.transform(_)))
}
}
我尝试将其作为
运行object Runner extends App {
override def main(args: Array[String]): Unit = {
val n1 = NewNodeRule(<foo/>, <bar/>, Seq.empty, "adding bar under foo")
val n2 = NewNodeRule(<garage/>, <car/>, Seq.empty, "adding car under garage")
ConfigTransformer.transform(<Root/>, Seq(n1, n2))
}
}
我收到编译错误
Error:(18, 56) type mismatch;
found : PartialFunction[Int,scala.xml.Node]
required: solutions.xml.ConfigRule
rules.reduceLeft((x, y) => x.transform(doc).andThen(y.transform(_)))
我做错了什么?
答案 0 :(得分:4)
我还不是Scala专家,但问题是你没有在ConfigRule
语句中返回reduceLeft
类型的对象(它是Node
,这就是你收到错误的原因)。你想要的是我猜foldLeft
。这是一个例子:
trait ConfigTransformer {
def transform(doc: Node, rules: Seq[ConfigRule]) = {
rules.foldLeft(doc)((d, x) => x.transform(d))
}
}
答案 1 :(得分:2)
嗯......问题是Seq[A]
的reduceLeft有以下签名,
def reduceLeft[B >: A](op: (B, A) ⇒ B): B
这意味着您的缩减功能op
应该使用accumulator: B
和currentElem: A
,并且应该返回B
,其中B
为super-class
A
reduceLeft
。
关于accumulator
的一个重要注意事项是第一次减少,即。使用Seq
的第一个和第二个元素作为参数完成Seq
的第一次计算。
换句话说......只有reduceLeft
中的元素才会参与foldLeft
。
对于您希望以其他值作为初始累加器开始的用例,您应该使用def foldLeft[B](z: B)(op: (B, A) ⇒ B): B
,其具有以下签名,
accumulator: B
请注意,它需要初始z
(fold
此处)和B
函数作为参数。另外...... foldLeft
这里可以是你想要的任何类型,与A没有任何关系。这就是你的情况,
现在,如果您想使用trait ConfigTransformer {
def transform(doc: Node, rules: Seq[ConfigRule]) =
rules.foldLeft(doc)((acc, elem) => elem.transform(acc))
}
,
getTransportInfo