2017-02-08 9 views
2

私は依存型について読んできました。何かを誤解していないことを確認するための質問が1つあります。これでWikipedia page on dependent types開始:コンピュータ科学とロジックでジェネリックは、依存型と同じ値でパラメータ化されていますか?

、依存の型は、その定義値に依存タイプです。 「整数の対」はタイプです。 「第2の値が第1より大きい整数の対」は、値に依存するため依存型です。


私は範囲の数を表すことができる言語があるとします。例えば

struct Int<Min, Max> 

を、タイプInt<0, 10>は0包括と10との間の排他的整数を表します。ボーナスとして

、私は一般的な分散を導入するとします。たとえば

struct Int<in Min, out Max> 

を、そのようInt<3, 10>Int<0, 8>ようなタイプのインスタンスは、タイプInt<0, 10>の変数に割り当てることができます。だから

Int<Min1 + Min2, Max1 + Max2> operator+(Int<Min1, Max1> op1, Int<Min2, Max2> op2); 

Int<0, 10>とを追加するタイプInt<3, 14>の結果を生成します:

今、このタイプの加算演算は次のようにシグネチャを持つことができます。そのようなタイプのシステムでは

、我々はまた、のようなペア、注文している可能性:ように

struct OrderedPair<Min, Mid, Max> 
{ 
    Int<Min, Mid> SmallerNumber; 
    Int<Mid, Max> LargerNumber; 
} 

をと。


これは従属型とは異なりますか?もしそうなら、どうですか?

+0

依存型を使用すると、型に述語を添付して、すべての操作でその述語が保持されていることを確認できます。システムをいくつかの述語(範囲の最小/最大など)に制限することができれば、それをオフロードして、ある程度のパラメータを入力することができます。ハスケルはそうすることを許していると聞いた。つまり、範囲内の数値やN個以下の要素のリストの実際的なケースでは、おそらくそれを達成することができます。一般的なケースでは、おそらくそうでないかもしれないが、なぜ人々は依存型言語を発明するだろうか? – 9000

+1

@ 9000ええ、私は基本的には、あるタイプ(この 'Int '、可能な 'List 'など)がビルディングブロックとして基本的に全体に届くかどうかを理解しようとしています従属型の型システム、または従属型システムは全く別のものです。 –

答えて

3

これは、タイプが値に依存することができる限定されたタイプの依存型ですが、これらの値はコンパイル時に使用可能でなければなりません。

Idrisのような完全に依存する型付き言語では、型はランタイム値にも依存する可能性があります。そのような値を構成するには、その値に型が入る範囲がproofである必要があります。証拠を得るための一つの方法は、簡単なテスト(擬似コード)である:

m = user_input(); 
n = user_input(); 

// Type error: n is not guaranteed to be in range. 
x = Int<0, m>(n); 

if (n >= 0 && n <= m) { 
    // Accepted: proofs of n >= 0 and n <= m in scope. 
    x = Int<0, m>(n); 
} 

ですから、C++(例えば)で、あなたの例を実装するが、Int<Min, Max>を構築すると、コンストラクタで動的なチェックを必要とすることができます。 C++に完全な依存型があった場合は、というコンストラクタを何らかの形式のチェック(静的または動的)なしで呼び出すことさえできませんでした。

+0

インスタンスを作成するために必要な証明に関する部分が私には意味があります。しかし、このコードでは、 'm'はランタイム値です。 'n '(無制限のint、おそらくは)から' Int <0, m> 'に移動しただけではなく、私が理解している部分です。しかし、 'Int <0, m>'には静的に知られていない値が含まれています。囲み関数は 'x'を返すことができますか?囲み関数の型は 'Int <0, m>'となりますか?もしそうなら、 'Int <0, m>'を 'Int <0, 5>'に代入しようとすると、コンパイラは多かれ少なかれ特定の型になるのかどうかをどのように知るでしょうか? –

+0

if文の 'x'の型は' Int <0, m> 'ですが、実行時の値がこのif-checkを渡すことがわかっていない(証明できません)ため、囲み関数の型はそれにできません。しかし、 '0'(または' m')を返すelse節があれば、全体の戻り値の型は 'Int <0, m>'です。 – laughedelic

+0

@TheodorosChatzigiannakis:私はあなたが存在感のある、∃mでそれをラップすることによって価値を返すことができると思います。 Int <0, m> 'の場合、呼び出し側は' m'の値でローカルに動作するようにアンパックすることができます。つまり、関数は "私はいくつかの* m *の範囲[0、* m *]の値を返します"と言います。存在する型は、この文脈では「従属対」または「シグマ型」と呼ばれ、それは値mとそれに依存するタイプ「Int <0, m>」の対であるためです。 –

関連する問題