20

DeriveFunctorGHC には などのいくつかの言語フラグがありDeriveDataTypeable、Haskell 98 で許可されている型クラス以外の型クラスの派生インスタンスをコンパイラで生成できますFunctor。自然な」派生インスタンス。

では、なぜMonoidですか?単一のデータ コンストラクターを持つ任意のデータ型のようです。

data T = MkT a b c ...

インスタンスを機械的に生成できMonoidます(疑似コードを許してください):

instance (Monoid a, Monoid b, Monoid c, ...) => Monoid T where
  mempty =
    MkT mempty mempty mempty ...
  mappend (MkT a1 b1 c1 ...) (MkT a2 b2 c2 ...) =
    MkT (mappend a1 a2) (mappend b1 b2) (mappend c1 c2) ...

派生パッケージがこれを提供していることは承知していますが、特に私の質問は、GHC が提供しない理由があるかどうかです。

4

2 に答える 2

18

を派生できないのは本当に恣意的な決定Monoidですが、モノイドも非常に一般的であるため、通常、型をモノイドにする方法はたくさんあります。次に例を示します。

data T = A | B | C deriving (Eq, Ord, Enum)

type Mon a = (a, a -> a -> a)

m1, m2, m3, m4 :: Mon T
m1 = (A, max)
m2 = (C, min)
m3 = (A, \ x y -> toEnum $ (fromEnum x + fromEnum y) `rem` 3)
m4 = (B, f4)
f4 A _ = A
f4 B x = x
f4 C _ = C

Tこれは、モノイドを作成する 4 つの妥当な方法を示しています(Mon単位と 2 項演算を含む)。1 つ目は最大値をとるモノイド、2 つ目は最小値をとるモノイド、3 つ目はモジュロ 3 算術のモノイド、4 つ目はそのOrdering型に使用されるモノイドです。自然な方法として際立っているものは何もありません。

于 2012-06-23T18:00:08.400 に答える
8

Numおよび他のいくつかのクラスについても同じことを求めることができます。それは重要ではありません: 他のすべての標準的な派生は、複数のコンストラクターを持つデータ型に対して機能します。

代わりに、 newtype deriving を使用できますnewtype T = MkT (a,b,c) deriving Monoid

同様の拡張: 空のデータ型をほぼすべての型クラスのインスタンスにすることができます。

このderiving句は、事前定義されたクラスに対してのみ機能するため、Haskell では常にアドホックで不便な部分でした。アドホックな拡張機能をさらに追加すると、言語が複雑になります。代わりに、GHC は最近ジェネリック派生のサポートを得ました。

于 2012-06-23T01:35:57.557 に答える