Анти-XML группа «collect» не собирает

#scala #anti-xml

#скала #анти-XML #scala

Вопрос:

Я перепостирую это от scala-user:

У меня есть следующее:

 object XmlTest {

  import com.codecommit.antixml._

  implicit def toPicker(nodes: Group[Node]): Picker = new Picker(nodes)

  class Picker(nodes: Group[Node]) {
    def pick[A <: Node : ClassManifest]: Group[A] = nodes collect {
      case a if implicitly[ClassManifest[A]].erasure.isInstance(a) => a.asInstanceOf[A]
    }
  }

  def testCollect(elems: Group[Elem]) {
    println("size before collect = "   elems.size)
    val es = elems collect {
      case e if e.name == "c" => println("element name is "   e.name); e
    }
    println("size after collect = "   es.size)
  }

  def main(args: Array[String]) {
    val xml = XML.fromString("<a><b/><c/><d/></a>")

    // this works because <a> has only elements as children
    testCollect(xml.children.asInstanceOf[Group[Elem]])

    // pick filters collection by type
    testCollect(xml.children.pick[Elem])
  }
}
  

Когда я запустил ее, она напечатала следующее:

 [info] size before collect = 3           // size is 3
[info] element name is c                 // element c matches
[info] size after collect = 1              // this is correct
[info] size before collect = 3           // size is the same as the previous case
[info] element name is c                 // element "c" is matched as well
[info] size after collect = 0               // this should be 1
  

Я здесь в растерянности. Что происходит?

Комментарии:

1. Маленькая деталь: вы можете написать classManifest[A] вместо implicitly[ClassManifest[A]] .

2. Вы должны были четко указать, что используете анти-xml.

Ответ №1:

Похоже, это ошибка в анти-XML. Это довольно легко воспроизвести даже без всей ClassManifest магии:

 val xml = <a><b/><c/><d/></a>.anti
xml.children collect { case e => e } collect { case e => e }   // => Group()
  

Проблема проистекает из реализации flatMap в Zipper . Что-то определенно не так, и неудивительно, учитывая, насколько нетривиальна реализация. Я добавлю тестовый пример и, надеюсь, исправлю его сегодня вечером.