2012-03-02 12 views
7

を与えるものではありません、私はスカラ座に新たなんだ、と私はSet.containsScalaのSet.containsが予想される型の不一致エラーに

に間違った引数を供給する場合、私は時々、型エラーを取得しない理由を理解するのに苦労していますここでREPL(2.9.1.final)を使用して、簡単な例です:

scala> val baz = Map("one" -> 1, "two" -> 2) 
baz: scala.collection.immutable.Map[java.lang.String,Int] = Map(one -> 1, two -> 2) 

scala> baz.values.toSet.contains("asdf") 
res3: Boolean = false 

私はそこ型の不一致を取得していないのはなぜ?

scala> val bling = baz.values.toSet 
bling: scala.collection.immutable.Set[Int] = Set(1, 2) 

scala> bling.contains("asdf") 
<console>:10: error: type mismatch; 
found : java.lang.String("asdf") 
required: Int 
       bling.contains("asdf") 
          ^

愚かな間違い、言語の微妙、またはコンパイラのバグ:私は別のvalbaz.values.toSetを割り当て、その上containsを呼び出す場合

、私はのget型チェックを行う

+0

(すなわちAny)短い答え考慮にcontains "Hi"を取り、IntのLUBを推測し、Stringされる:言語微妙(サブタイピングと型推論) –

答えて

12

OK、そうSetはその型パラメータで不変であり、あなたが言うように、それは、まさにそのはず

scala> Set(1, 2, 3) contains "Hi" 
<console>:8: error: type mismatch; 
found : java.lang.String("Hi") 
required: Int 
       Set(1, 2, 3) contains "Hi" 
            ^

のように動作します。しかし:

scala> Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet contains "Hi" 
res1: Boolean = false 

我々は合理的にISに来ることができる唯一の結論問題のSetのタイプがではなく、Set[Int]であることを確認してください。 Set[Int]が必要なスカラーを明示的に指定するとどうなりますか?明示的な型のパラメータを持つコードの同じ部分(すなわち、それがコンパイルされない)だけで正常に動作:

scala> Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet[Int] contains "Hi" 
<console>:8: error: type mismatch; 
found : java.lang.String("Hi") 
required: Int 
       Map('a -> 1, 'b -> 2, 'c -> 3).values.toSet[Int] contains "Hi" 
                     ^

問題がtoSetメソッドに渡される推論型パラメータあります。 Scalaは明らかに

+0

をあなたは* Scalaは***その後の使用状況から推測されていることを言っています**セットの型パラメータは 'Any'のようなより広範なものにすべきですか? –

+0

くそー、それに私を打つ。 +1してください。さらに説明すると、 'baz.values.toSet.contains(" asdf ")'を呼び出すと、条件[X:Int]を満たす最も近い型が見つけられ、 'X'は' Any' 'は、あなたの' toSet'の結果が 'Set [Any]'であることを意味します。このため、あなたは明示的にどのタイプを設定する必要があります、と言わなければならないように言われています。 – Dylan

+0

'Set'の型を' Any'と推論していると説明してはいけませんか? –

関連する問題