5

Scala(2.10)では、私がList(1.0, 2)それを要求すると、期待どおりに、を取得しList[Double]ます。

だが...

私が求める場合、Map(1.0 -> 'A', 2 -> 'B')私はを取得しMap[AnyVal, Char]ます。キーのタイプを教えてDoubleください。を要求Map[Double, Char](1.0 -> 'A', 2 -> 'B)すると、「2」でタイプの不一致が発生します。

これは私が最も混乱していると思います!矛盾していませんか?

余談です List[(Double, Char)]((1.0, 'A'), (2, 'B')).toMapが、Map [Double、Char]を教えてください。

4

2 に答える 2

6

Scalaの型階層を調べると、プリミティブ型がサブ型/スーパー型の関係にないことがわかります。ただし、数値の拡大と呼ばれるメカニズムがあります。これにより、たとえば、引数を取るメソッドを呼び出すことができます。Doubleたとえば、。を渡すことができますInt。thenは自動的にに「Int拡張」されDoubleます。

List(1.0, 2)これがあなたに与える理由ですList[Double]

しかし、MapコンストラクターはTuple[A, B]引数を取ります。数値の拡大は高次の型には適用されないため、数値型を混在させると、ターゲット型の推論は機能しません。

case class Test[A](tup: (A, Char)*)
Test(1.0 -> 'A', 2 -> 'B') // AnyVal

さらに、矢印演算子->は邪魔になります。

Test[Double](2 -> 'B') // found: (Int, Char)  required: (Double, Char)

これは、私が思う型推論のもう1つの制限です。タプルの記述a -> bは、のシンタックスシュガーで(a, b)あり、の暗黙的なメソッドによって提供さany2ArrowAssocPredefます。この間接参照がない場合、Tuple2直接構築すると、次のように機能します。

Test[Double]((2, 'B'))

したがって、数値の拡大はまだ機能しませんが、少なくとも次のタイプを適用できます。

Map[Double, Char]((1.0, 'A'), (2, 'B'))

数値拡大の動作を示す最後の例:

def map[A, B](keys: A*)(values: B*) = Map((keys zip values): _*)
map(1.0, 2)('A', 'B') // Map[Double, Char]
于 2013-01-19T17:50:31.223 に答える
3

リストの場合、型宣言なしで、Scalaはすべての要素を調べて、共通の型を見つけようとします。あなたの場合、IntはDoubleに変換できるので、混合リストをList [Double]に変換して、1つのIntをプロモートします。

Mapコンストラクターは、一連の2タプルを取ります。タプルのリストを作成した場合も、同じ動作が得られます。

scala> List((1, "one"), (2.0, "two.oh"))
res0: List[(AnyVal, String)] = List((1,one), (2.0,two.oh))

Tuple2 [Int、String]をTuple2 [Double、String]に自動的に昇格させることはできません。この場合、型宣言でコンパイラを少し支援する必要があります。

scala> val x: List[(Double, String)] = List((1, "one"), (2.0, "two.oh"))
x: List[(Double, String)] = List((1.0,one), (2.0,two.oh))

また

scala> val x = List[(Double, String)]((1, "one"), (2.0, "two.oh"))
x: List[(Double, String)] = List((1.0,one), (2.0,two.oh))

またはあなたの場合:

scala> val x = List[(Double, String)]((1, "one"), (2.0, "two.oh")).toMap
x: scala.collection.immutable.Map[Double,String] = Map(1.0 -> one, 2.0 -> two.oh)

何らかの理由で、Mapで型宣言を使用しても機能しません。理由がわからない:

scala> val x = Map[Double, String](1 -> "one", 2.0 -> "two.oh")
<console>:7: error: type mismatch;
found   : (Int, String)
required: (Double, String)
   val x = Map[Double, String](1 -> "one", 2.0 -> "two.oh")
于 2013-01-19T17:46:50.217 に答える