2012-04-21 6 views
10

encodingパッケージは、ビルドスクリプト(Setup.hs)にHaXmlを使用しています。 HaXml-1.19とHaXml-1.22の間で変更されたインタフェースのビットを使用することがあります。エンコーディングパッケージがいずれのバージョンでもビルドできたらいいですね。私はSetup.hsのビルド方法の変更

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

のようなものをやって、つまり、通常の陰謀団のトリックを使用してみました...しかし、パッケージが設定されており、このファイルはのconfigureステップを可能にするために構築されている前に、魔法の定義が存在することはできません。私の選択肢は何ですか? cabal-installがSetup.hsをコンパイルするために呼び出すコマンドを変更する方法はありますか?条件付きでカバールを回避する別のメカニズムがありますか?

+0

インターフェイスの変更はどのように厳しいですか?どのような変更がありますか?テンプレートhaskellは、あなたが何であるかに応じてあなたを救助することができるかもしれません。 –

+0

@benmachine唯一本当に変わったのは、 'Element'コンストラクタが' data QName = N String | 'SomethingIDon'tCareAbout'を' String'の代わりに使用します。 'Setup.hs'ファイルは' Element'コンストラクタを関数(常に文字列 'String'と一緒に)とパターンマッチング(時には文字列' String'と時にはcatch-all可変パターン)で使用します。 –

+0

'QName'が存在するときに' toQName = N'と 'fromQName'が' Ns'を 'Just s'にするような関数' toQName'と 'fromQName'を持っていれば十分でしょう。 ')、' QName'が存在しないときは 'toQName = id'と' fromQName = Just'のどちらかです。次に、ビューパターンで必要なことをすることができるかもしれませんか?私は 'toQName'と' fromQName'は私の[notcppパッケージ](http://hackage.haskell.org/package/notcpp) –

答えて

4

Data.Dataインターフェイスは、存在するかもしれないし、存在しないかもしれない型の値を構築し、分解することができます(ちょっと!)。残念ながら、HaXmlはその型のインスタンスがDataではないようです。存在するかもしれないし、存在しないかもしれない型を参照することができないので、定義することはできません。

次のモジュール輸出qnameCompat:テンプレートのHaskellを使用してトップレベルでスプライシングされた場合Nが存在する場合

{-# 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 

qnameCompatがチェックされます。それがない場合は、次のコードを生成します:

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

れていない場合は、以下が生成されます

type QName = String 
toQName = id 
fromQName = Just 

今、あなたは、例えば、Element Sを作成し、解体することができますViewPatterns拡張子を使用して:

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

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

ViewPatternsすることはもちろん、基本的な便利ではなく、次のとおりです。同じようにうまく動作しますfromQNameの結果に通常のパターンマッチングを使用しました。

(これらのアイデアはmaybeReifyや他のいくつかの便利なユーティリティが含まれnotcpp packageを開発するために私を導いたものです)

+0

これは素晴らしいですね。 –

2

あり、あなたの最善の策は、バージョンのテストを行い、その後、一度本当のSetup.hsに手渡すスタブSetup.hsファイルを作成することであってもよいので、Setup.hsのコンパイルを制御cabal-install/Distribution/Client/SetupWrapper.hsに非常に多くのノブもしていないようですそれはバージョンが何であるかを把握しています。

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

質問すると本物の質問かもしれませんが、これはなぜですかSetup.hsは外部ライブラリを使用していますか?

+0

Hmのヘルプと同様のアイデアを使って、テンプレートのhaskellで定義できます?まだ私が手渡しているものを(両方)構築しようとしないのですか? –

+0

そうです、適切なマクロ定義でGHCを再起動する必要があります。 –

関連する問題