Scala2.8のMapでapplyとかimplicitとか

備忘録的メモ。
Map(1->2,3->4)を丁寧に?読み解く。自分理解なので突っ込み歓迎。

//こうはできない
scala> new Map(1->2,3->4)
<console>:7: error: trait Map is abstract; cannot be instantiated
      new Map(1->2,3->4)
      ^

これはなんなのか。

//第一段階
scala> Map.apply(1->2,3->4)
res24: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)

こうなる。object MapがextendsしているMapFactoryのapplyメソッドを呼び出す。
applyメソッドの引数が可変長引数になっているため、複数つっこめるのは判断できるが、applyメソッドの引数はtupleのpairとなっている。
が、渡しているのは1->2などとなっている。
この1->2という書き方は、(1).->(2)だが、Intには->というメソッドは存在しない。
ここで暗黙のレシーバー変換が登場する。
型エラーを検出し、Intから->をもっている型への変換をさがしにいく。
この場合、Predefにあるany2ArrowAssocを探しだし*1、1:IntはArrowAssocクラスに型変換され、ArrowAssocの->メソッドが呼び出される。

scala> Map.apply(any2ArrowAssoc(1).->(2),any2ArrowAssoc(3).->(4))
res29: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
//こう。
scala> Map.apply(new ArrowAssoc(1).->(2),new ArrowAssoc(3).->(4))  
res32: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)

ArrowAssocの->メソッドはTupple2を返すので・・

//こうなる
scala> Map.apply(Tuple2(1,2),Tuple2(3,4))                        
res35: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
//Tuple2(1,2)もapplyだけど省略
scala> Map.apply((1,2),(3,4))            
res36: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)

*1:[A]はAny