さっしーブログ

埼玉県在住のシステムエンジニアです。基本的には技術的な内容を中心に発信していきます。

正格と非正格(遅延)について

現在Scalaを勉強中です。

今回はScalaの参考書を読んでいると出てくる「正格」と「非正格(遅延)」について学習しました。

まず初めに、正格とは何でしょうか?非正格(遅延)とは何でしょうか?

これは関数の特性を指します。 正格な関数..つまり正格関数とは引数を常に評価します。

サンプルコードは以下

object sample {

  def main(args: Array[String]): Unit = {
  hoge(1 + 1)
  }

  private def hoge(x: Int): Unit = {
  println(x)
  }
}

正格関数ではhogeメソッドに渡している「1+1」の評価された値が hogeメソッドの引数「x」にわたってきます。 つまり「x」には「2」が入ってます。

これが正格の特性です。

次に非正格(遅延)関数は引数をすぐに評価しません。 つまり引数を評価されない状態で受け取ることができます。

この評価されていない形式のことをサンクと呼ぶそうです。

ではScalaでどのようにして引数を評価されていない状態で受け取るのでしょうか?

サンプルコードは以下

object sample {

  def main(args: Array[String]): Unit = {
  val hogeInt: Int = hoge(true,
  {println("On"); 1},
  {println("Off"); 0}
  )
  println(hogeInt)
  }

  private def hoge(isOn: Boolean, on: => Int, off: => Int): Int = {
  if(isOn) on else off
  }
}

hogeの関数に注目してください。

評価させない引数の型の左側に「=>」というものがありますね。

こうすることで引数を評価せずにhogeが受け取り、 その受け取った引数が関数内で参照されない限り式は評価されません。

上記のサンプルコードで言いますと「on」という変数の中には「println("On"); 1」という式が入っており、 ifの条件で「true」になったら「on」を参照します。

そして「on」が参照されたときに初めて「println("On"); 1」が評価されて、 「On」という文字列を表示して「1」を返すのです。

ということで今回は正格と遅延とはこういうものだということを勉強しました。

以上