score:1

Given that `unselect` currently just returns a `Zipper[Node]`, I don't see a way to get what you want without bossing the type system around a bit, and that's going to take something like a cast.

In this case you really do know something the type system can't, given the current state of the Anti-XML library: you know that the parent of the zipper resulting from your transformation is a `Zipper[Elem]`, and therefore that what `unselect` gives you actually will be a `Zipper[Elem]`, even though it's typed as a `Zipper[Node]`.

So I think the best you can do is package up the unpleasantness a little more cleanly:

``````def toEndo(t: Elem => Zipper[Elem]): Elem => Elem =
``````

Or, to make your intent more apparent:

``````def toEndo(t: Elem => Zipper[Elem]) = t andThen (_.unselect.head match {
case e: Elem => e
case _ => throw new RuntimeException("Aaaaah! This was never meant to happen!")
})
``````

Then you can write the following:

``````val transforms: Seq[Elem => Zipper[Elem]] = Seq(
_ \\ "book" filter (_.attrs("year").toInt > 2000),
_ \\ "book" filter (_.attrs("title").contains("J"))
)

val result = Function.chain(transforms map toEndo)(lib)
``````

Note that I've moved the `unselect` into the helper to give us a bit more type safety.