"implicit" を調べる

scala 子ネタです。

implicit conversion も implicit parameter も便利なわけですが、如何せんどこから降って沸いてきたのか分からない、ということが多いのが困り物です。
例えば Array[T] の先頭要素が欲しいときには、

scala> Array(1, 2, 3).head
res0: Int = 1

なんて書けちゃうわけですが(パターンマッチ使えというのはもっともですが、しかしこれは単なる例です)さてこの head は Array のメソッドではない。となると implicit conversion が行われているはず、しかし一体何に変換されているんだろう…

こういうときは repl が使えるなら repl の :implitics コマンドが使えます。:implicits コマンドは implicit な定義を列挙することができます。まあこれを使えば大体は分かるはずです。-v オプションも必要ならお忘れなく。
それでダメなときには implicitly ジェネリックメソッドを利用しましょう。

scala> implicitly[Array[Int] => { def head : Int}]
res1: (Array[Int]) => AnyRef{def head: Int} = <function1>

で implicit conversion を行うメソッドが取得できるので、後は reflection を利用して、

scala> implicitly[Array[Int] => { def head : Int}].getClass.getMethods.head.getReturnType.getName
res2: java.lang.String = scala.collection.mutable.ArrayOps

とかで返り値型の名前が分かります。便利ですね!

implicit parameter の例は…まだ scala 詳しくないのであんまりいい例は出せませんごめんなさい。まあでもちゃんと使えます。

scala> implicitly[Numeric[Int]].getClass.getName
res3: java.lang.String = scala.math.Numeric$IntIsIntegral$

こういうの haskell でも何かないんですかね。おしまい。