web-dev-qa-db-ja.com

C ++の概念はHaskell型クラスとどう違うのですか?

ConceptsTSのC++のコンセプトは、最近GCCトランクにマージされました。概念を使用すると、型が概念の条件を満たすように要求することで、ジェネリックコードを制約できます(たとえば、「比較可能」)。

Haskellには型クラスがあります。私はHaskellにあまり詳しくありません。概念と型クラスはどのように関連していますか?

34
jbcoe

概念(Concepts TSで定義されている)と型クラスは、ジェネリック関数で使用できる型のセットを制限するという意味でのみ関連しています。それを超えて、私は2つの機能が異なる方法しか考えられません。

私はHaskellの専門家ではないことに注意してください。それからは程遠い。しかし、私はConcepts TSの専門家です(私はそれを書き、GCCに実装しました)。

  • 概念(および制約)は、型がセットのメンバーであるかどうかを決定する述語です。型が概念のモデル(型クラスのインスタンス)であるかどうかを明示的に宣言する必要はありません。これは一連の要件によって決定され、コンパイラーによってチェックされます。実際、概念では「TCのモデルです」と書くことはできませんが、これはさまざまなメタプログラミング手法を使用して簡単にサポートされます。

  • 概念は、型以外の引数を制約するために使用できます。また、constexpr関数とテンプレートメタプログラミングにより、記述したいほとんどすべての制約を表現できます(たとえば、範囲が素数でなければならないハッシュ配列)。 。これは型クラスには当てはまらないと思います。

  • 概念は型システムの一部ではありません。それらは宣言の使用を制限し、場合によってはテンプレート引数の推論を制限します。型クラスは型システムの一部であり、型チェックに参加します。

  • 概念は、モジュラー型のチェックまたはコンパイルをサポートしていません。テンプレート定義は概念に対してチェックされないため、インスタンス化中にレイトキャッチタイプエラーが発生する可能性がありますが、これによりライブラリライターにある程度の柔軟性が追加されます(たとえば、アルゴリズムにデバッグコードを追加してもインターフェイスは変更されません)。型クラスは型システムの一部であるため、汎用アルゴリズムをモジュール式でチェックおよびコンパイルできます。

  • Concepts TSは、制約の順序に基づいた一般的なアルゴリズムとデータ構造の特殊化をサポートします。私はHaskellの専門家ではないので、ここに同等のものがあるかどうかはわかりません。見つかりません。

  • 概念を使用しても、実行時のコストが増えることはありません。前回調べたとき、型クラスは仮想関数呼び出しと同じランタイムオーバーヘッドを課す可能性がありましたが、Haskellはそれらを最適化するのに非常に優れていることを理解しています。

機能(Concepts TS)と機能(Haskell型クラス)を比較すると、これらが大きな違いだと思います。

しかし、2つの言語には根本的な哲学的な違いがあります-そしてそれはあなたが書いているC++のどんなフレーバーに対しても機能的ではありません。 Haskellはモジュール式になりたいと考えています。モジュール式であることには多くの素晴らしい特性があります。 C++テンプレートはモジュール式を拒否します。インスタンス化時のルックアップにより、実行時のオーバーヘッドなしでタイプベースの最適化が可能になります。これが、C++ジェネリックライブラリが幅広い再利用と比類のないパフォーマンスの両方を提供する理由です。

43
Andrew Sutton

あなたは次の研究論文に興味があるかもしれません:

「C++の概念とHaskell型クラスの比較」、Bernardy et al。、WGP 2008. Pdf詳細

更新:ペーパーの短い要約として:ペーパーは、C++の概念の用語とHaskell型クラスの用語の間の正確なマッピングを定義し、このマッピングを使用して2つの間の詳細な機能比較を提供します。

彼らの結論は言う:

表2に要約されている27の基準のうち、16は両方の言語で同等にサポートされており、移植性がないのは1つまたは2つだけです。したがって、開始時に安全に結論を下すことができます— C++の概念とHaskell型クラスは非常に似ています。

T.C.が指摘したように以下では、このペーパーがConceptsTSではなくC++ 0xの概念を比較していることを指摘する価値があります。私は違いを説明する良い参考文献を知りません。

17