あなたは誤解してInt with Stringいます。これはIntとStringの結合ではなく、交差点であり、IntとStringの場合は空です。文字列である値のセットとIntである値のセットではなく、文字列の特性を持つIntの特性を持つ値のセットでもあります。そのような値はありません。
を使用しEither[Int, String]て、を使用できますMap[Left(1) -> 2, Right("Hello") -> 3)。どちらも正確には共用体ではなく、AU Bではなく、識別された共用体A + Bです。Either[Int、Int]はIntと同じではないという違いを理解できます。実際、これは(Int、Boolean)と同型です。Intがあり、どちら側でもあることがわかります。AとBが互いに素である場合(IntとStringがそうであるように)、A+BとAUBは同型です。
または(気の弱い人向けではありません)、MilesSabinによる共用体型の可能なエンコーディングを見ることができます。(既存のクラスMapで実際に使用できるかどうかはわかりませんが、試してみるよりも確実ではありませんが、それでも最も興味深い読み物になります)。
編集:質問とコードを読むのが速すぎます、ごめんなさい
下限Int with Stringはと同じNothingであるためMap[_ >: Int with String, Int]、はと同じでMap[_ >: Nothing, Int]あり、Nothing下限が暗示されているため、これはMap[_, Int]です。あなたの実際MapはMap[Any, Int]です。Int with Stringにもかかわらず、ブールキーを追加することもできます。val宣言が機能するようにAMap[Any, Int]を入力できます。Map[_, Int]ただし、入力すると、キーのタイプに関するすべての情報が失われます。キーのタイプがわからないため、テーブルから何も追加(取得)できません。
可能なキーがないため、UpperBoundはこれ以上良くありませんでした。最初のval宣言でさえ失敗します。
編集2:に関してif (true) Map(1 -> 2) else Map("1" -> 2)
これはと同じではありませんMap(1 -> 2, "1" -> 2)。とのより一般的なスーパータイプと同様Map[Any, Int]に、それはより単純で、単純にです。AnyIntString
一方、Map(1 -> 2)は、、Map[Int, Int]およびMap["1", 2]ですMap[String, Int]。との共通のスーパータイプを見つけるという問題がありますが、との共通のスーパータイプをMap[Int, Int]見つけることMap[String, Int]はできません。IntString
実験してみましょう。Map2番目のパラメーターは共変です。キーではなく値としてIntandを使用する場合:String
if (true) Map(1 -> 2) else Map(1 -> "2")
res1: scala.collection.immutable.Map[Int, Any]
共分散を使用すると、すべての型パラメーターに共通のスーパータイプを使用するだけです。
反変型の場合:
class L[-T]
object L{def apply[T](t: T) = new L[T])
class A
class B extends A
class C
if (true) L(new A) else L(new C)
res2: L[A with C]
if (true) L(new A) else L(new B)
res3: L[B]
交差点を取りますA with C.WhenBはのサブタイプでありA、AwithBはちょうどBです。
2つのタイプが関連している場合、Mapの非バリアントパラメータを使用するようになりました
if (true) Map(new A -> 1) else Map(new B -> 1)
res4: scala.collection.immutable.Map[_ >: B <: A, Int]
そのようなタイプは役に立たないわけではありません。タイプのキーを使用して値にアクセスしたり、値を追加したりできますB。ただし、キーの値にアクセスすることはできませんA。これは実際のマップにあるものなので(のでtrue)、頑張ってください。にアクセスするkeySetと、と入力されSet[A]ます。キーの種類に関する情報が不完全であり、実行できることは限られていますが、マップの種類に関する知識が限られていることを考えると、これは必要な制限です。を使用Int and Stringすると、最小限の情報が得られ、下限Anyと上限はに相当しNothingます。Nothingの上限により、キーをパラメーターとして受け取るルーチンを呼び出すことができなくなります。keySetタイプが下限Set[Any]である、を引き続き取得できます。Any