2011-10-11 12 views
12

Scalaのコンパイラは、現在、以下のコードScalaコンパイラを拡張して、戻り型の再帰メソッドを推測することはできますか?

def foo(i:Int) = if (i > 0) foo (i-1) else 0 

のように再帰的なメソッドの戻り値の型を推論することはできません上記の文のいずれかのambuigityはありますか? (すなわち、Int以外の任意のタイプですか?

もっと複雑な例では、そのタイプを推測することは想像できます。

種類を推測できる(再帰的な)方法のケースをさらに特徴付けることは可能ですか?

[編集:]コンパイラは、Stringが間違っていることを理解するのに十分なインテリジェントです。あなたの再帰呼び出しが最後の位置に常にある場合

scala> def foo(i:Int):String = if (i > 0) foo (i-1) else 0 
<console>:5: error: type mismatch; 
found : Int(0) 
required: String 
+2

は 'Double'は別の可能なタイプです。 – Jus12

+1

http://stackoverflow.com/questions/3739133/why-does-scala-require-a-return-type-for-recursive-functions/3739174#3739174 – retronym

+2

@ Jus12 'foo:Double 'はそのままで可能です'def f = 2'を':Double'として宣言することができます。しかし、コンパイラは 'def f = 2'を':Int'と推論します。分かりやすい再帰型推論器はあなたの例と同じ理由で 'foo:Double'を仮定しません。 – Debilski

答えて

6

、すなわち、その値が使用されることはありませんとだけ、他のすべてのブランチの共通スーパータイプとしてのタイプを決定することが可能である必要があり、返さ。オブジェクトの存在下で、より複雑になっているもの - それは実際にfoo上の方法であるため

しかし、

def foo(i: Int) = if (i > 0) foo(i - 1) + 1 else 0 

ような状況で、あなたは操作+foo(i - 1) + 1の種類を知っている(または理解できないでしょう)fooのことを知らずに。だから、再びあなたはサークルで動き回っています。

3

Scalaが提供するよりもはるかに強力な統合アルゴリズムが必要です。 Scalaは、左から右、上から下への型チェックを行います。だから、推論は次のようにやや行くだろう:

What is the type of expression "if (i > 0) foo(i - 1) + 1 else 0"? 
Unify "foo(i - 1) + 1" and "0" 
What is the type of "foo(i - 1) + 1"? 
What is the type of "foo(i - 1)" 
What is "foo"? 
foo is the current definition, so we don't know it's type 
error 

あなたがifをした場合、あなたの周りの他の方法があるだろう:

私は推測
What is the type of expression "if (i <= 0) 0 else foo(i - 1) + 1 "? 
Unify "0" and "foo(i - 1) + 1" 
What is the type of "0"? 
"0" <: Int >: Nothing 
What is the type of "foo(i - 1) + 1"? 
What is the type of "foo(i - 1)" 
What is "foo"? 
foo is the current definition, so we don't know it's type 
error 
+0

Scalaコンパイラがどのように型を推論するかについての良い説明。 – Jus12

関連する問題