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を開発するために私を導いたものです)
インターフェイスの変更はどのように厳しいですか?どのような変更がありますか?テンプレートhaskellは、あなたが何であるかに応じてあなたを救助することができるかもしれません。 –
@benmachine唯一本当に変わったのは、 'Element'コンストラクタが' data QName = N String | 'SomethingIDon'tCareAbout'を' String'の代わりに使用します。 'Setup.hs'ファイルは' Element'コンストラクタを関数(常に文字列 'String'と一緒に)とパターンマッチング(時には文字列' String'と時にはcatch-all可変パターン)で使用します。 –
'QName'が存在するときに' toQName = N'と 'fromQName'が' Ns'を 'Just s'にするような関数' toQName'と 'fromQName'を持っていれば十分でしょう。 ')、' QName'が存在しないときは 'toQName = id'と' fromQName = Just'のどちらかです。次に、ビューパターンで必要なことをすることができるかもしれませんか?私は 'toQName'と' fromQName'は私の[notcppパッケージ](http://hackage.haskell.org/package/notcpp) –