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 CTElement1
、CTElement2
などのファミリを作成することを想像できます。Int
CTElement
ct_cayleytable
理想的には、おそらく のような暗黙のパラメーターを使用して、このポインターのコピーを 1 つだけ渡すためのトリックがあるかもしれません?cayleytable
が、これは互換性のない複数の Cayley テーブルではうまく機能せず、一般的に不快になります。
また、ベクトルへのインデックスはコモナドと見なすことができることもわかりました。最終的に実行時に行う場合でも、この種の型チェックをスムーズにするのに役立つベクトルまたは何かの素敵な comonad インスタンスはありますか?