5

次のように、代数型クラスの「階層」を作成しようとしています。

class Semigroup a where
  (.*) :: a -> a -> a
  foldr1 (.*) = foldl1 (.*)   -- GHCi error: "`foldr1' is not a (visible) method of class `Semigroup'"

class (Semigroup a) => Monoid a where
  identity :: a
  (.*) identity = id :: a -> a  -- GHCi error: "`.*' is not a (visible) method of class `Monoid'"

class (Monoid a) => Group a where
  inverse :: a -> a

したがって、グループはモノイドであり、モノイドは半群です。ただし、クラスが親クラスの関数を認識できないというエラーが発生します。

これらのエラーは私を悩ませます。なぜなら、(たとえば)書くことによってclass (Semigroup a) => Monoid a、クラスMonoid aは関数を見ることができると思ったから(.*)です。さらに、プレリュードのタイプにはfoldr1制約がないのでfoldr1、このコンテキストで機能すると思いました。

4

2 に答える 2

6

Haskellでは、方程式を項で宣言(または強制)することはできません(やりたいように思えます)。これは非常に実用的な理由によるものです。Haskellのように豊富なプログラミング言語で任意の用語間の同等性を証明することは決定不可能です。人間が作成した証明をチェックすることはしばしば決定可能ですが、プログラミング中にこれらの証明を作成して追跡しなければならないこともやや面倒です。

それでも、これがあなたが定期的にやりたいことのようなものであるなら、これを可能にする言語があります。検索する用語は「依存型」です。たとえば、CoqとAgdaは、おそらく現時点で最も人気のある2つの依存型言語であり、それぞれが、法を順守する優れた半群(またはモノイド)のみが存在する型を作成することを非常に簡単にします。

于 2011-07-14T00:50:05.670 に答える
4

あなたが何をしようとしているのかわからない。

in のデフォルト値とfoldr1inのデフォルト値を指定しようとしている場合は、できません。Semigroup(.*)Monoid

  • foldr1Prelude で非型クラス関数として定義されているため、ローカルで定義することはできませんSemigroup
  • (.*)Semigroupクラスの一員です。インスタンスで値Semigroupを指定でき、クラスでデフォルト値を指定できますが、クラス (またはインスタンス)Semigroupでその値を指定することはできません。MonoidMonoid

inのデフォルト値と(.*)inのデフォルト値を指定しようとしている場合は、間違った構文を使用しています。SemigroupidentityMonoid

代わりに次のようなものを試してください

class Semigroup a where
    (.*) :: a -> a -> a
    (.*) = {-something-}

また

class Semigroup a where
    (.*) :: a -> a -> a
    x .* y = {-something-}
于 2011-07-13T08:29:30.737 に答える