5

Cayley Tableを使用するためにいくつかの計算ツールを一般化することに興味があります。つまり、ルックアップ テーブル ベースの乗算演算です。

次のように最小限の実装を作成できます。

date CayleyTable = CayleyTable {
    ct_name :: ByteString,
    ct_products :: V.Vector (V.Vector Int)
} deriving (Read, Show)

instance Eq (CayleyTable) where
 (==) a b = ct_name a == ct_name b

data CTElement = CTElement { 
    ct_cayleytable :: CayleyTable,
    ct_index   :: !Int
}

instance Eq (CTElement) where
 (==) a b = assert (ct_cayleytable a == ct_cayleytable b) $
            ct_index a == ct_index b

instance Show (CTElement) where
   show = ("CTElement" ++) . show . ctp_index

a **** b = assert (ct_cayleytable a == ct_cayleytable b) $
           ((ct_cayleytable a) ! a) ! b

ただし、このアプローチには、ByteString比較による実行時の型チェックから始めて、read正しく動作させることができないという事実を含め、多くの問題があります。これを正しく行う方法はありますか?

IO を実行する場合を除いて、乗算を提供し、それらの型の一貫性を検証する型クラスを使用して、 newtypes CTElement1CTElement2などのファミリを作成することを想像できます。IntCTElement

ct_cayleytable理想的には、おそらく のような暗黙のパラメーターを使用して、このポインターのコピーを 1 つだけ渡すためのトリックがあるかもしれません?cayleytableが、これは互換性のない複数の Cayley テーブルではうまく機能せず、一般的に不快になります。

また、ベクトルへのインデックスはコモナドと見なすことができることもわかりました。最終的に実行時に行う場合でも、この種の型チェックをスムーズにするのに役立つベクトルまたは何かの素敵な comonad インスタンスはありますか?

4

1 に答える 1

1

Haskell の型チェッカーは型のみをチェックするということを認識する必要があります。したがって、CaleyTable はクラスである必要があります。

class CaleyGroup g where
caleyTable :: g -> CaleyTable
... -- Any operations you cannot implement soley by knowing the caley table

data CayleyTable = CayleyTable {
...
} deriving (Read, Show)

コンパイル時に caleyTable がわからない場合は、ランク 2 の型を使用する必要があります。コンパイラは、CaleyTable が存在するという不変条件を適用する必要があるため、コードで使用する場合。

manipWithCaleyTable :: Integral i => CaleyTable -> i -> (forall g. CaleyGroup g => g -> g) -> a

たとえば、実装できます。CaleyTable でグループ操作を実行できます。結合することで機能iCaleyTable、3 番目の引数に渡す新しい型を作成します。

于 2012-05-23T15:20:28.023 に答える