ikeike443のブログ

ソフトウェアビジネスに関心がある系のブログ

今日覚えたこと

scala> "ab" map Map('a'->'b', 'b'->'c')
res109: String = bc

なぜこれが動くのか。

Map#apply

http://www.scala-lang.org/api/current/scala/collection/Map#apply(A):B

Retrieves the value which is associated with the given key. This method invokes the default method of the map if there is no mapping from the given key to a value. Unless overridden, the default method throws a NoSuchElementException.
key the key
returns the value associated with the given key, or the result of the map's default method, if none exists.
Definition Classes
MapLike → GenMapLike → Function1

上記の通り、MapのapplyはKeyを引数にとってValueを返す。
よって、このapplyメソッドが呼ばれたものと考えられる。

なぜ Map#applyが呼ばれるのか

map の引数は関数であることが要求される。つまり、上記のMapは関数として評価されていると考えられる。
下記と等価。

"ab" map ( Map('a'->'b', 'b'->'c').apply _ )

同じ事を自分で定義したクラスやオブジェクトで出来るか?

下記だとNG。なぜなら関数ではないから。

scala> object a {
     |   def apply(s: Char) = s.toInt
     | }
defined module a
scala> "ab" map a
<console>:9: error: type mismatch;
 found   : a.type (with underlying type object a)
 required: Char => ?
              "ab" map a
                       ^


関数として定義すればいい。下記のように実装すればOK。

scala> object b extends (Char => Int) {
     |   def apply(s: Char) = s.toInt
     | }
defined module b

scala> "ab" map b
res111: scala.collection.immutable.IndexedSeq[Int] = Vector(97, 98)

Mapは関数なの?

はい。
http://www.scala-lang.org/api/current/scala/collection/Map#apply(A):B
上記に書いてあります。Map#applyはFunction1で定義されているものらしい。


という理解をした。