LoginSignup
1
2

More than 5 years have passed since last update.

末尾最適化の練習メモ

@pizyumiさんの以下の記事で実装している再帰処理を末尾最適化に書き直しながら練習した記事です。

列の要素の総和を返すsumメソッド。

  • ふつうの再帰
  def sum(xs: List[Int]): Int = xs match {
      case Nil => 0
      case x :: xs1 => x + sum(xs1)
    }
  • 末尾最適化
  def sum(xs: List[Int]): Int = {
    def sum(xs: List[Int], z: Int): Int = xs match {
      case Nil => z
      case x :: xs1 => sum(xs1, z + x)
    }

    sum(xs, 0)
  }

列の要素の数を返すlengthメソッド。

  • ふつうの再帰
  def length[T](xs: List[T]): Int = xs match {
      case Nil => 0
      case x :: xs => 1 + length(xs)
  }
  • 末尾最適化
  def length[T](xs: List[T]): Int = {
    def length[T](xs: List[T], z: Int): Int = xs match {
      case Nil => z
      case _ :: xs1 => length(xs1, z + 1)
    }

    length(xs, 0)
  }

列の最大の要素を返すmaxメソッド。

  • ふつうの再帰
  def max(xs: List[Int]): Int = xs match {
    case List(x) => x
    case x :: xs => { val m = max(xs); if (m > x) m else x }
  }
  • 末尾最適化
  def max(xs: List[Int]): Int = {
    def max(xs: List[Int], z: Int): Int = xs match {
      case Nil => z
      case x :: xs1 if x > z => max(xs1, x)
      case x :: xs1 => max(xs1, z)
    }
    max(xs, xs.head)
  }

列の全ての要素が述語を充足するかを返すforallメソッド。

  • 末尾最適化
  def forall[T](f: T => Boolean)(xs: List[T]): Boolean = xs match {
    case Nil => true
    case x :: xs1 if !f(x) => false
    case x :: xs1 => forall1(f)(xs1)
  }

列のある要素が述語を充足するかを返すexistsメソッド

  • 末尾最適化
  def exists[T](f: T => Boolean)(xs: List[T]): Boolean = xs match {
    case Nil => false
    case x :: _ if f(x) => true
    case _ :: xs1 => exists(f)(xs1)
  }

列の中で述語を充足する最初の要素を返すfindメソッド。

  • 末尾最適化
  def find[T](f: T => Boolean)(xs: List[T]): Option[T] = xs match {
    case Nil => None
    case x :: _ if f(x) => Some(x)
    case _ :: xs1 => find(f)(xs1)
  }
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2