2017-05-10 6 views
2

私はHustley-Milnerを使ってRustの型推論がとても良いと読んでいます。 Rustにも可変変数があり、AFAIKは、HMアルゴリズムが過大化する可能性があるため、可変性で動作する場合にはいくつかの制約が必要です。以下のコード:第2の行の整数で推定された浮動小数点値を整数変数に割り当てることができないのでRustはHindley-Milnerの変異をどのように解決しますか?

let mut a; 
a = 3; 
a = 2.5; 

は、コンパイルされません。だから私は、単純な変数の場合、非ジェネリック型が推論されるとすぐに、変数がモノ型になり、もはや一般化できないと推測しています。

しかし、Vecのようなテンプレートはどうですか?たとえば、次のコードのようになります。

let mut v; 
v = Vec::new(); 
v.push(3); 
v.push(2.3); 

これはもう一度失敗しますが、もう一度最後の行です。これは、第2行がタイプを部分的に推測し(Vec)、第3行がコンテナタイプを推測したことを意味する。

ルールは何ですか?私が知らない価値の制限のようなものがありますか?それとも、私は物事が複雑すぎて、Rustはもっと厳しい規則を持っています(一般化は全くありません)?私は間違っていないよ場合

+2

ラスト型推論をレビューする作業が進行中です.Niko Matsakisは、新しい統一エンジンについてのブログを書いています。[統一インチョーク - パート1](http://smallcultfollowing.com/ babysteps/blog/2017/03/25 /統一 - チョーク - パート-1 /)と[チョークの統一 - 第2部](http://smallcultfollowing.com/babysteps/blog/2017/04/23/unificationインチョークパート2 /)。 @MatthieuM。 –

+0

。ありがとう、私はこれを読むよ! –

答えて

2

rustcがその型の推論でやや熱心であることは(診断の質が向上する限り)問題とみなされます。

私たちはあなたの最初の例をチェックした場合:

let mut a = 3; 
a = 2.5; 

を次に最初の行はa{generic integer type}を有し、第2行は、それはありませんので、2.5aに割り当てることができないことを診断するのにつながると推測につながります汎用整数型。

代わりに、より良いアルゴリズムが競合を登録し、各タイプが来たラインをポイントすることが期待されます。多分、我々はChalkでそれを得るでしょう。

注:一般的な整数型は整数リテラルを "ポリモフィック"にするためのトリックです。特定の整数型に他のヒントがない場合は、デフォルトでi32になります。


2番目の例は、基本的に同じ方法で発生します。詳細は

let mut v = Vec::new(); 
v.push(3); 

  • vが割り当てられているタイプ$T
  • Vec::new()Vec<$U>
  • 3を入力作り出すので{integer}

を入力作り出す、最初の行に、我々が得ます$T == Vec<$U>となり、2行目で$U == {integer}となるので、vVec<{integer}>と推定されます。

正確な整数型を学習する他のソースがない場合は、デフォルトでi32に戻ります。


ここでは、変更可能性は実際には推論に影響しないことにご留意ください。型推論、またはタイプ統一の観点から、以下のコードサンプルは、等価である:

// With mutability: 
let mut a = 1; 
a = 2.5; 

// Without mutability: 
let a = if <condition> { 1 } else { 2.5 }; 

はHM、Derefに関してサブタイピングとしてはるかに困難な来ると錆にはるかに悪い問題があります。

4

それはこの行いますVECスニペット用

let mut a; 
a = 3;  //here a is already infered as mut int 
a = 2.5; //fails because int != float 

let mut v; 
v = Vec::new();// now v type is Vec<something> 
v.push(3);  // v type is Vec<int> 
v.push(2.3); // here fails because Vec<int> != Vec<float> 

お知らせ私はさび型を使用しますが、単に一般的な考えを持つためではありませんでした。

+0

アルゴリズムに一般化が必要ないと言っていますか? –

+0

@ PeterLenkefi、最初に特殊化された完全型が見つかるまで一般化されます – Netwave

+1

@PeterLenkefi「一般化しない」とはどういう意味ですか? 'v = Vec :: new()'は事実上、いくつかの 'T'に対して' v:Vec 'という制約です。 'v.push(3)'は 'T = {integer}'(これはそうでない場合には 'i32'にデフォルト設定されます)という制約です。どのようにこれらの制約のいずれかをより一般化することができますか? – trentcl

関連する問題