5

次の問題は型演算を使用して解決できると思いますが、まだ解決策が見つかりません。

問題

バイナリ/テキスト ファイル (json、xml など) から解析する文字列から値 (Tries を実装として使用) への有限マップがあります。

type Value = ...
type Attributes = Data.Trie Value 
data Object = Object Attributes

各マップには同じ型の値がありますが、キーのセットは同じではありません。特定のキーを必要とする特殊な機能がある場合に常にタイプを切り替える必要がないように、同じキーのセットを持つマップをグループ化します。

data T1
data T2 
...

data Object a where
    T1 :: Attributes -> Object T1
    T2 :: Attributes -> Object T2
    ...

これにより、次のようなものを書くことができます。

f1 :: Object T1 -> ...

それ以外の

f1 :: Object ->
f1 o | check_if_T1 o = ...

これは機能しますが、2 つの欠点があります。

  1. Object の同種リストは異種混合になりました。つまり、リスト [Object] はもう持てません。
  2. 属性を取得/設定するには、多くのボイラープレートを記述する必要があります。

    get :: Object a -> Attributes
    get (T1 a) = a
    get (T2 a) = a
    ...
    

質問

  1. ADT のコンストラクターに応じて関数を特殊化するより良い方法はありますか?
  2. リスト [オブジェクト] を持つ能力を取り戻すにはどうすればよいですか? 特定のタイプのみを許可する特別なバージョンの Dynamic はありますか? オブジェクトをもう一度ラップすることを考えましたが、これは多くのボイラープレートを追加します。例えば、

    データ TObject = TT1 T1 | TT2 T2 ...

私が必要とするのは:

get :: a -> TObject -> Object a

私が導出できるように:

collect :: a -> [TObject] -> [Object a]

HList を調べましたが、私の問題には合わないと思います。特に、[Object] の型の順序はコンパイル時にわからないためです。

これは機能依存性/型演算を使用して解決できるように思えますが、まだ良い方法を見つけていません。

4

1 に答える 1

2
  1. すべてのコンストラクターがモノモーフィック型を返し、Object再帰がない場合は、個別の型を使用することだけを検討することをお勧めします。それ以外の

    data T1
    data T2
    
    data Object a where
        T1 :: Attributes -> Object T1
        T2 :: Attributes -> Object T2
    

    検討

    data T1 = T1 Attributes
    data T2 = T2 Attributes
    
  2. Dynamicは 1 つの方法であり、上記を使用するderiving Typeableと、追加するだけで完了できます。または、手動で行うこともできます。

    data TSomething = It's1 T1 | It's2 T2
    
    getT1s :: [TSomething] -> [T1]
    getT2s :: [TSomething] -> [T2]
    getT1s xs = [t1 | It's1 t1 <- xs]
    getT2s xs = [t2 | It's2 t2 <- xs]
    

    あなたが言うように、これには定型文が少し含まれます。Typeableバージョンは少し見栄えがします。

    deriving Typeable T1
    deriving Typeable T2
    
    -- can specialize at the call-site to
    -- getTs :: [Dynamic] -> [T1] or
    -- getTs :: [Dynamic] -> [T2]
    getTs :: Typeable a => [Dynamic] -> [a]
    getTs xs = [x | Just x <- map fromDynamic xs]
    
于 2012-05-23T18:34:16.403 に答える