GHC拡張を使用して任意の長さのタプルに一般化する新しい型クラスを定義できますか?任意の長さのタプルにインスタンス定義を持つ新しい型クラス
PreludeとBase(いくつかのクラスは最大15要素のタプルをサポートしています。最大7つまで)の組み込みクラスの動作とこれらのクラスを拡張する可能性については、すでにいくつか質問があります。
前奏曲と基本行動:私は少し異なる質問をしてい Extend a Show instance to a Tuple of any size
が新しい定義でショーを拡張します。全く新しいタイプのクラスを作成している場合、任意の長さのタプルを処理するインスタンスルールを追加することは可能でしょうか(おそらくGHC拡張を使用します)。
ここに、PartialOrderというクラスの例があります。私は、次のルール
(a,b ... , z) <= (a1,b1, ... , z1) iff (a <= a1) && (b <= b1) && ... && (z <= z1)
ここで、従来の「いくつかの任意のサイズまでのタプルのためのクラスを定義する」アプローチを使用して定義での私の最初の刺しだを使用して任意のサイズのタプルを部分的に比較することができるようにしたいです。
任意の長さのタプルをカバーするインスタンス定義を記述するために使用できるGHC拡張はありますか?
テンプレートハスケルや外部プログラムを使って定義を事前に生成できますが、C++テンプレートのようにオンデマンドで生成することはできません。
-- Sets equipped with the (is_subset) operation are an example of a
-- partial order.
--
-- {} < {a} less than
-- {} = {} equal to
-- {a, b} > {b} greater than
-- {a} ~ {b} incomparable
--
-- in order to define a partial order we need a definition of (<=)
data PartialOrdering = POLessThan | POGreaterThan | POEqual | POIncomparable deriving (Eq, Show)
class PartialOrder a where
lessThanEq :: a -> a -> Bool
instance PartialOrder PartialOrdering where
lessThanEq POIncomparable _ = False
lessThanEq _ POIncomparable = False
-- with incomparables dealt with...
lessThanEq POLessThan _ = True
lessThanEq POEqual POLessThan = False
lessThanEq POEqual _ = True
lessThanEq POGreaterThan POGreaterThan = True
lessThanEq POGreaterThan _ = False
-- note this is different from the semantics for Ord applied to tuples,
-- which uses lexicographic ordering.
--
-- (a,b) is less than or equal to (c,d) iff
-- a <= b and c <= d
-- 2 element tuple
instance (PartialOrder a, PartialOrder b) => PartialOrder (a, b) where
lessThanEq (a,b) (c,d) = (lessThanEq a c) && (lessThanEq b d)
-- 3 element tuple
instance (PartialOrder a, PartialOrder b, PartialOrder c) => PartialOrder (a, b, c) where
lessThanEq (a,b,c) (d,e,f) = (lessThanEq a d) && (lessThanEq b e) && (lessThanEq c f)
-- 4 element tuple
instance (PartialOrder a, PartialOrder b, PartialOrder c, PartialOrder d) => PartialOrder (a, b, c, d) where
lessThanEq (a,b,c,d) (e,f,g,h) = (lessThanEq a e) && (lessThanEq b f) && (lessThanEq c g) && (lessThanEq d h)
-- etc.
main = putStrLn "hi"
だけの提案:なぜあなたは長インデックスリストを使用していませんか?そのようなデータ型はタプルと同型である。 GADTを使用して定義するのは簡単です。 –