Box[A]=A が出来る不思議

Liftのファイルアップロードのサンプルコードで

var fileHolder : Box[FileParamHolder] = Empty

(略)

bind(...
  "receipt" -> SHtml.fileUpload(fileHolder = _),

という部分がある。SHtml.fileUpload()の仕様を見ると、引数型は FileParamHolder => Any ということで、関数リテラルの内容は、というと、型的には以下のような関係になるはず。(これはあくまで例なので意味のあるコードではありません)

Box[FileParamHolder] = FileParamHolder

なんでこんなこと出来るのかがいまのところよくわからない。さっそく調べてみて気がついたこと

  • Box[T] は Product trait を実装している
  • FileParamHolder は Product trait を実装している
  • FileParamHolderのソースには with Product などとは書かれていない

そもそも上記のような代入が出来るのはなぜか、という疑問に Product trait が関係しているかどうかはまったく不明。
でも、Productって何? なんで勝手に with Product になってるのと思っていろいろ実験してみた。

scala> case class A();
defined class A

scala> (new A).isInstanceOf[Product]
res1: Boolean = true

scala> class B();
defined class B

scala> (new B).isInstanceOf[Product]
res2: Boolean = false

どうやら case class は自動的に with Product とされるようだ。ふむふむ。で、Productって何よ、という話はまだ勉強中。