20

標準ライブラリの型クラスのいくつかについて、「Monad には Functor が必要」、「Monad には Applicative が必要」、「Applicative には Pointed が必要」、「Num には Show が必要ない」などと不満を言う人をたくさん見てきました。など、いくつか質問があります。

  1. 型クラスの依存関係のツリーがコミュニティによって認識された「欠陥」を持っている方法についての議論はありますか、それともこれは単に物事が歴史的に行われた方法の結果ですか?

  2. これを大幅に変更すると、既存のコードがどの程度壊れるでしょうか?

  3. クラス依存関係の「正しい」セットを実装する基本型クラス (特にアロー、モナド、アプリカティブなど) の代替実装はありますか?

4

4 に答える 4

18

下位互換性以外にも、Haskell が型クラスを扱うかなり単純な方法に起因する (ほとんどは表面的なものですが、対処するのが面倒な) 問題がいくつかあります。

上向きの暗黙的な定義はありません:はandMonadだけで完全に定義されます。そしてそれらの言葉で書くことができます。「適切な」階層では、各インスタンスを書き出す必要があります。この場合はそれほど悪くはありませんが、粒度が上がるにつれて、それぞれがいくつかの小さな機能を追加するインスタンスの数も増えます。クラス定義が独自の関数に関してスーパークラス関数のデフォルトの実装を提供できれば、物事は大幅に簡素化されます。そのため、スーパークラス内の複数の関数を完全に包含するような関数は、関連する階層全体の定義として機能できます。pure(>>=)fmap(<*>)(>>=)

Context bloatNum : and を必要Showとする「理由」がある限りEq、それは数値の等価性を印刷して比較することがかなり一般的であるためです。これらは厳密に直交していますが、それらを分離すると、3 つすべてを実行する関数は、その型で 3 つのクラスすべてを指定する必要があります。これは技術的には良いことですが、繰り返しになりますが、粒度が上がると関数型のシグネチャも大きくなります。

モノリシックな依存関係: 型クラスとそのスーパークラスの階層を追加することはできますが、変更または置換することはできません。コードの一部が、共通の型クラスの独自のバージョンを置き換える必要があると感じた場合 (たとえば、このようなものを使用して置き換えるMonad場合)、階層はその時点で切断されます。の他の定義を使用するコードとの互換性は、Monadある程度手動で提供する必要があり、他の定義の上に構築された型クラスは、両方の定義が共有する動作のサブセットのみに依存している場合でも、再実装または変換する必要があります。

明確に正しい階層はありません: 上記で暗示されているように、クラスの粒度には選択が必要です。たとえば、Pointed本当に存在する必要があるのでしょうか、それともApplicative十分でしょうか? ここには、普遍的に理想的な答えはありませんし、存在する必要もありません。

既存の型クラスを置き換える作業は、最初に上記の問題に取り組むことでよりうまく機能するのではないかと思います。その後、型クラスを置き換えることは、はるかに苦痛が少なくなるか、形式的なものにすぎません。たとえば、@luqui が言及している型クラス シノニムの提案は、この方向への大きな一歩となるでしょう。

于 2011-04-20T14:31:27.763 に答える
5

Haskell-primeリストでこれについて最近議論されていますが、そこから生じたのは、階層の変更を行うには、JónFairbairnの提案を最初に実装する必要があるということです。これにより、非常に重要なポイントが修正されます1 @camccanのリストの:型クラスは、そのスーパークラス定義のデフォルトの実装を与えることができます。私はその提案の実装、あるいはその提案の途中の正式な仕様さえ知りません。

型クラスの同義語の修正ポイント#2、コンテキストの肥大化。使用に問題がなければ、すでにそれを実行できることに注意してくださいUndecidableInstances(そして、タイプを推測するたびにGHCに同義語を拡張させます...)

#4に関しては、#1と#2に適切な修正を加えることで、実際的な問題のほとんどが修正されます。単なる粒度の問題ではない場合(型クラスの同義語全体のインスタンスの記述を含む同義語があります)、複数の可能なスーパークラスを選択できる場合、これは数学的な問題になると思いますNum-階層その解決策(代替サブクラス?)には、途中で#3を解決する可能性がかなりあります。

いずれにせよ、(階層だけでなく)Haskellにこれらの変更を加えると、HaskellとHaskellの両方のコードが確実に柔軟になり、否定的な発言者の下でラグが引き出されるため、努力する価値があると思います。現在の引数。

于 2011-04-22T10:02:52.000 に答える
2
  1. 私は代理的存在に反対します。また、Applicative-Functor-Monad 階層に関連する提案を称賛することもできません。私は何年も前に、数学的に健全なプレリュードの必要性についてつぶやきました。

  2. 型クラス階層に対する 1 つの障害は、モノイドの最初の部分にあります。たとえば、整数は加法的モノイドと乗法的モノイドの両方を形成します。 Coqは多重継承によってこれを解決します。

    建設的な数学証明システムを備えた数学的階層を持つことの大きな利点の 1 つは、Curry-Howard 同型を介して証明からプログラムを抽出できることです。プログラムの正確性と自動検証に関心がある人にとっては、Haskell 型クラスと Coq のような証明検証ツールとの間の直接変換が便利です。

    現在、hmatrixパッケージとその仲間を使用しています。残念ながら、現在の Numeric Prelude on hackage ではうまく機能しないと思います。理想的には、汎用コードで最適化された BLAS および LAPACK ライブラリを使用するには、Numeric Prelude で指定された型クラス インターフェイスを実装するだけでよいはずです。

于 2011-05-17T04:28:15.807 に答える
1
  1. 身元不明の人物 (Vivian McPhail を通じて活動) は、前奏曲のこの領域の改革を提案し、「標準クラス階層は、論理ではなく、Haskell の歴史的発展の結果である」と述べて提案を開始します。これが本当かどうか、私には言えません。

  2. 上記の提案には、下位互換性をサポートするための措置が含まれていますが、決して完璧ではないようです。

  3. 混乱の一部を片付けるために、 The Other Preludeを作成するという短いながらも輝かしい試みがありました。

于 2011-04-20T13:13:36.713 に答える