Scalaでカリー化を使ってみる

1.実装するプログラム

URLのパスを作るプログラムを作ってみたいと思います。 /親1/親2/子供というパスで、子供が沢山いるパターンです。

親1をa、親2をbとしてみます。

2.カリー化を使わない方法

object PathCreator {
  def main(args: Array[String]) {
    val parent1 = "a"
    val parent2 = "b"
    val children = Seq("1.png", "2.png", "3.png")

    val paths = pathCreator(parent1, parent2, children)
    paths.foreach(println)
  }

  def pathCreator(parent1: String, parent2: String, children: Seq[String]): Seq[String] =
    children.map(child => pathCreate(parent1, parent2, child))

  def pathCreate(parent1: String, panret2: String, child: String) =
    s"/$parent1/$panret2/$child"
}

次のように書くことになり、処理すべき対象であるchildrenがわかりづらくなります。

val paths = pathCreator(parent1, parent2, children)
children.map(child => pathCreate(parent1, parent2, child))

3.親1と親2を受け取って、子供を処理する関数を使う方法

object PathCreator {
  def main(args: Array[String]) {
    val parent1 = "a"
    val parent2 = "b"
    val children = Seq("1.png", "2.png", "3.png")

    val paths = pathCreator(parent1, parent2)(children)
    paths.foreach(println)
  }

  val pathCreator = (parent1: String, parent2: String) =>
    (children: Seq[String]) => children.map(child => pathCreate(parent1, parent2, child))

  def pathCreate(parent1: String, panret2: String, child: String) =
    s"/$parent1/$panret2/$child"
}

次のように書くことができて、処理すべき対象がchildrenだということがわかりやすくなります。

val paths = pathCreator(parent1, parent2)(children)

4.カリー化して書いてみる

3.のようなことをやる場合は、カリー化を使うことができます。

object PathCreator {

  def main(args: Array[String]) {
    val parent1 = "a"
    val parent2 = "b"
    val children = Seq("1.png", "2.png", "3.png")

    val paths = pathCreator(parent1, parent2)(children)
    paths.foreach(println)
  }

  def pathCreator(parent1: String, parent2: String)(children: Seq[String]) =
    children.map(child => pathCreate(parent1, parent2, child))

  def pathCreate(parent1: String, panret2: String, child: String) =
    s"/$parent1/$panret2/$child"

}

変わっているのはpathCreator関数だけです。よりシンプルにわかりやすく書くことができますね。

Phone

Address


Fukuoka, Fukuoka