読者です 読者をやめる 読者になる 読者になる

Scalaはコンストラクタもカリー化できる!の続き

前回記事の続きです。

scalaはコンストラクタもカリー化できる! - rabitarochanの日記

ブログへのコメントや、Twitterのリプライでいろいろ教えていただきました。
@さん、@さん、ありがとうございました!

一部の引数を指定したコンストラクタ

一部の引数を指定したコンストラクタについては、前回失敗した書き方を少し変えることで可能でした。

scala> class Person(val name: String)(val age: Int)
defined class Person


// 失敗・・・
scala> val p1 = new Person("rabitarochan") _
<console>:8: error: missing arguments for constructor Person in class Person
       val p1 = new Person("rabitarochan") _
                ^

// 成功!!!
scala> val p2 = new Person("rabitarochan")(_)
p2: Int => Person = <function1>

_ と (_) って何が違うの!?という疑問については前回記事のコメントか、@kmizuさんのブログ、

_ と _ の違い - ((プログラミング | 形式) 言語) について書く日記

にかかれてます。

case class の場合

例では普通のクラスを利用していましたが、case class を利用した場合は、以下のとおりにインスタンス化できます。

scala> case class Person(name: String)(age: Int)
defined class Person

scala> val p1 = Person("rabitarochan") _
p1: Int => Person = <function1>

case class を定義すると、コンパニオンオブジェクトも自動的に定義されます。
この場合、コンパニオンオブジェクトの apply メソッドに対して部分適用された関数が返ります。

手動でコンパニオンオブジェクトを定義した場合でも、同じ動きを確認できました。

// コンパニオンオブジェクトの定義は :paste してから。
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person(val name: String)(val age: Int)
object Person {
  def apply(name: String)(age: Int) = new Person(name)(age)
}

// Exiting paste mode, now interpreting.

defined class Person
defined module Person

scala> val p1 = Person("rabitarochan") _
p1: Int => Person = <function1>

まとめ

new Hoge("hoge")(_) と記述することで、カリー化したコンストラクタについても、部分適用(というの??)した関数を取得することができました。カリー化した場合の制限だと思っていたものも解決しました。

あとは、@kmizuさんのブログを読んで理解するだけです。
言語仕様も読まないとなぁ・・・。