SE情報技術研究会’s blog

http://se-info-tech.connpass.com

2016-01-23 第13回 関数型プログラミング勉強会(Scala)の振り返り part.1

第6章 純粋関数型の状態

前回の続きより

純粋関数型の命令型プログラミング

本では下記の定義がある

val ns: Rand[List[Int]] =
  int.flatMap(x =>
    int.flatMap(y =>
      ints(x).map(xs => 
        xs.map(_%y))
    )
  )

これをダウンロードしたサンプルで実装しようとするとコンパイルエラーになる。

まず、ここでのRandはtype Rand[+A] = RNG => (A, RNG)ではなくStateで定義されたRandである。

ただし、ダウンロードしたサンプルのStateにはintやintsはない。

動かすためには下記を行う。

  • このns: Rand[List[Int]]のRandはobject State内で定義されているRandを使う。
  • intsはサンプルには定義されてないがExercise 6.7で定義されているものを使う。
  • intは定義されていないので自分で定義する必要がある。 ※ State内で定義すると楽です。
object State {
  type Rand[A] = State[RNG, A]

  …略

  val ns: Rand[List[Int]] = {
    int.flatMap(x => 
      int.flatMap(y =>
        ints(x).map(xs => xs.map(_ % y))))
  }

  // 
  def int: Rand[Int] = State(rnd => {
    rnd.nextInt
  })

  // Exercise 6.7より
  def ints(count: Int): Rand[List[Int]] = {
    sequence(List.fill(count)(int))
  }
}

ちなみに本でポイントにしたいのは下記

  • 命令型プログラミングを行うにはfor内包表記を使うとコードがわかりやすい