3

hxt を問題なく使用していますが、最初から問題がありました。次のコードを想像してみてください

liftKeys = atTag "myKeys" >>>
   proc e -> do
      key1 <- getAttrValue "name"   -< e
      key2 <- getAttrValue "chance" -< e
      returnA -< (key1, key2)

私は多くのドキュメントを解析するためにそのように使用してきましたが、古典的なプログラミングの問題である抽象化の欠如の前に私はそれを使用しました。

<zone id= "greenhill">
  <key name="a" chance = "10" />
  <key name="v"  chance = "10"/>
</zone>

この例のように、解析するファイルが 4 つ (およびさらに増える予定) あります。2 つの属性を持っているものもあれば、5 を持っているものもあれば、1 を持っているものもあります。私のファイルが持っている属性の量に応じて、異なるバージョンの liftKeys を書くことはできません。問題は、矢印や何をしているのかを本当に理解していないということです uu より単純なコードを書くには、いくつかの折り畳みまたは何かが必要です。

これのより良い使い方を知っていますか?

4

1 に答える 1

3

属性の数が異なる場合は、属性名のリストから矢印を作成するのが最も自然な解決策のようです。ただし、これを行うには、矢印のリストを、リストを生成する単一の矢印に変換する小さなヘルパー関数が必要になります。

arrowList :: Arrow a => [a b c] -> a b [c]
arrowList []         = arr $ const []
arrowList (a:arrows) = proc b -> do
    c  <- a -< b
    cs <- arrowList arrows -< b
    returnA -< (c:cs)

おそらく、このようなものはすでにいくつかの矢印ユーティリティ ライブラリに存在しますが、クイック検索では見つけることができませんでした。ここでは、 arrow のリストが与えられた場合、まず最初の矢印にフィードし、次にリストの残りを再帰的にマージして、そのマージされた矢印にフィードすること[a b c]により、それらを単一の矢印にマージします。bb

説明を簡単にするためにアロー表記を使用して上記の関数を書きましたが、次のように簡単に実装できます。

arrowList :: Arrow a => [a b c] -> a b [c]
arrowList []         = arr $ const []
arrowList (a:arrows) = a &&& arrowList arrows >>> arr (uncurry (:))

liftKeysこれで、このような関数を実装できます

liftKeys :: ArrowXml a => [String] -> a XmlTree [String]
liftKeys keys = atTag "myKeys" >>> arrowList (map getAttrValue keys)

上記の元の例は、次のように表すことができますliftKeys ["name", "chance"]

于 2012-02-04T11:51:25.130 に答える