10

エンコーディングパッケージは、ビルドスクリプト( )でHaXmlSetup.hsを使用します。HaXml-1.19とHaXml-1.22の間で変更されたインターフェイスのビットを使用することがあります。エンコーディングパッケージがどちらのバージョンでもビルドできればいいのにと思います。私は通常のカバルトリックを使ってみました、すなわち、次のようなことをします

{-# LANGUAGE CPP #-}
#if MIN_VERSION_HaXml(1,22,0)
-- HaXml-1.22 code
#else
-- HaXml-1.19 code
#endif

...しかし、パッケージが構成される前に魔法の定義は存在できません。このファイルは、構成手順を可能にするために作成されています。私のオプションは何ですか?cabal-installがコンパイルするために呼び出すコマンドを変更する方法はありますSetup.hsか?カバールを回避するコードを条件付きで選択するための別のメカニズムはありますか?

4

2 に答える 2

4

インターフェイスは、Data.Data存在する場合と存在しない場合があるタイプの値を構築および分解することができます(ほぼ!)。残念ながら、HaXmlにはDataその型のインスタンスがないようです。また、存在する場合と存在しない場合がある型を参照できないため、インスタンスを定義できません。そのため、テンプレートHaskellを使用する必要があります。

次のモジュールはエクスポートしますqnameCompat

{-# LANGUAGE TemplateHaskell #-}
module HaXmlCompat (qnameCompat) where

import Language.Haskell.TH

qnameCompat :: Q [Dec]
qnameCompat = do
  mi <- maybeReify "N"
  case mi of
    Nothing -> sequence [
      tySynD (mkName "QName") [] [t| String |],
      valD [p| toQName |] (normalB [| id |]) [],
      valD [p| fromQName |] (normalB [| Just |]) []]
    Just (DataConI n _ _ _) -> do
      s <- newName "s"
      sequence [
        valD [p| toQName |] (normalB (conE n)) [],
        funD (mkName "fromQName") [
          clause [conP n [varP s]] (normalB (appE [| Just |] (varE s))) [],
          clause [ [p| _ |] ] (normalB [| Nothing |]) []]]
    Just i -> fail $
      "N exists, but isn't the sort of thing I expected: " ++ show i

maybeReify :: String -> Q (Maybe Info)
maybeReify = recover (return Nothing) . fmap Just . reify . mkName

Template Haskellを使用してトップレベルでスプライスされると、存在qnameCompatするかどうかをチェックNします。含まれている場合は、次のコードが生成されます。

toQName = N
fromQName (N s) = Just s
fromQName _ = Nothing

そうでない場合は、次のように生成されます。

type QName = String
toQName = id
fromQName = Just

Elementこれで、たとえばViewPatterns拡張機能を使用して、を作成および分解できます。

myElt :: String -> Element i
myElt = Elem (toQName "elemName") [] []

eltName :: Element i -> String
eltName (Elem (fromQName -> Just n) _ _) = n

ViewPatternsは便利ですが、もちろん必須ではありません。結果に通常のパターンマッチングを使用しfromQNameても、同様に機能します。

(これらのアイデアは、私がnotcppパッケージmaybeReifyを開発するきっかけとなりました。これには、その他の便利なユーティリティが含まれています)

于 2012-04-25T10:57:55.210 に答える
2

cabal-install/Distribution/Client/SetupWrapper.hsのコンパイルを制御する際のノブはそれほど多くないようです。そのため、バージョンテストを実行するスタブSetup.hsファイルを作成し、バージョンがわかったらSetup.hs実際に渡すのが最善の策です。Setup.hsは。

もう1つのトリックは、セットアップスクリプトが使用する互換性シムライブラリを作成することです。これには、適切なバージョンのトリックがあります。

しかし、おそらく本当の質問は、これです:なぜSetup.hs外部ライブラリを使用しているのですか?

于 2012-04-23T16:32:01.853 に答える