3

次のようなanti-xml Elemがあります(自動生成データ):

<library>
  <bookshelf number="0">
    <book year="1997" title="Puzzled Coordinators" author="Lily Williams"></book>
    <book year="2005" title="Jittery Fare" author="Lucy Taylor"></book>
    <book year="2001" title="Dizzy Jurisdiction" author="Lucy Robinson"></book>
  </bookshelf>
  <bookshelf number="1">
    <book year="1997" title="Bashful Trusts" author="Lucas Wilson"></book>
    <book year="2003" title="Outrageous Consequences" author="Byron White"></book>
    <book year="1992" title="Irritated Accusations" author="Anne Roberts"></book>
  </bookshelf>
</library>

そして、それにいくつかの変換を適用したいと思います。たとえば、次のようになります。

val transforms: Seq[...] = ...
val result = transforms.foldLeft(library)(l,t) => t(l))

しかし、私はこの解決策までしか得られませんでした:

val transforms: Seq[Elem => Zipper[Node]] = Seq(
  x => x \\ "book" filter (_.attrs("year").toInt > 2000) unselect,
  x => x \\ "book" filter (_.attrs("title").contains("J")) unselect
)
val result = transforms.foldLeft(lib)((l,t) => t(l).head.asInstanceOf[Elem])

変換 (Elem => Elem) のより良い型を取得し、それらの醜いキャストを回避する方法はありますか?

4

1 に答える 1

1

unselect現在 a を返すだけであることを考えるとZipper[Node]、型システムを少し変更せずに必要なものを取得する方法がわかりません。それにはキャストのようなものが必要になります。

この場合、Anti-XML ライブラリの現在の状態を考えると、型システムができないことを本当に知っています: 変換の結果として生じるジッパーの親が であることがわかっているため、実際に得られるものZipper[Elem]はaとして入力されていても、 a 。unselectZipper[Elem]Zipper[Node]

したがって、あなたができる最善のことは、不快感をもう少しきれいにパッケージ化することだと思います。

def toEndo(t: Elem => Zipper[Elem]): Elem => Elem =
  t andThen (_.unselect.head.asInstanceOf[Elem])

または、あなたの意図をより明確にするために:

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!")
})

次に、次のように記述できます。

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)

unselect型の安全性をもう少し高めるために、 をヘルパーに移動したことに注意してください。

于 2012-08-19T17:17:36.583 に答える