次から始めましょう
data A = A String deriving Show
data B = B String deriving Show
class X a where
spooge :: a -> Q
[ Some implementations of X for A and B ]
ここで、それぞれ show' と read' という名前の show と read のカスタム実装があり、Show をシリアル化メカニズムとして利用しているとします。show' と read' に型を持たせたい
show' :: X a => a -> String
read' :: X a => String -> a
だから私は次のようなことができます
f :: String -> [Q]
f d = map (\x -> spooge $ read' x) d
データがあった可能性のある場所
[show' (A "foo"), show' (B "bar")]
要約すると、共通の型クラスを共有するさまざまな型のものをシリアル化したいので、逆シリアル化されたものでそれらの個別の実装を自動的に呼び出すことができます。
さて、次のようなラッパー型を生成するテンプレート haskell を記述できることに気付きました。
data XWrap = AWrap A | BWrap B deriving (Show)
ラップされた型をシリアライズして、型情報が保存されることを保証し、少なくとも XWrap を取り戻すことができるようにします...しかし、haskell ninja-ery を使用するより良い方法はありますか?
編集
さて、もっとアプリケーション固有にする必要があります。これは API です。ユーザーは、自分の As、B、および f を適切と思われるように定義します。XWrapやスイッチなどを更新する残りのコードをハッキングしてほしくありません。私が妥協しても構わないと思っているのは、すべての A、B などの 1 つのリストを何らかの形式で作成することです。なんで?
これがアプリケーションです。Aは「FTPサーバーからファイルをダウンロードする」です。Bは「flacからmp3に変換」です。A には、ユーザー名、パスワード、ポートなどの情報が含まれています。B にはファイル パス情報が含まれます。多くの A と B が存在する可能性があります。数百。喜んでプログラムにコンパイルしてくれる人がたくさんいます。2はほんの一例です。A と B は X であり、X を「チケット」と呼びます。Q は IO () です。Spooge は runTicket です。チケットを関連するデータ型に読み込んでから、ディスク上のものから読み取ったものに対して runTicket を実行する汎用コードを記述したいと考えています。ある時点で、シリアル化されたデータに型情報を詰め込む必要があります。