2015年5月24日日曜日

scala関数型デザイン&プログラミング P86

Exercise 5.1 StreamをListに変換し、それによりストリームを強制的に評価する関数を記述せよ。
なぜか、REPLではうまくいかなかった。eclipseでこんな感じで確かめてみた。末尾再帰でないので、あまりよくないらしい。解答にはよりよい方法がのっていた。

import Stream._
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]

object Main {
   def main(args:Array[String]) = {
println(Stream(1,2,3).toList)

trait Stream[+A] {
  def toList: List[A] = this match {
    case Empty => List()
    case Cons(h,t) => h() :: t().toList

  }
}

object Stream {
  def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
    lazy val head = hd
    lazy val tail = tl
    Cons(() => head, () => tail)
  }

  def empty[A]: Stream[A] = Empty

  def apply[A](as: A*): Stream[A] =
    if (as.isEmpty) empty
    else cons(as.head, apply(as.tail: _*))
}

こちらが模範解答だが、なかなか思いつかないかも
def toList: List[A] = {
  def go(s: Stream[A], acc: List[A]): List[A] = s match {
    case Cons(h,t) => go(t(), h() :: acc)
    case _ => acc
  }
  go(this, List()).reverse
}

0 件のコメント:

コメントを投稿