Skip to content

Instantly share code, notes, and snippets.

@y-yu
Last active August 29, 2015 14:19
Show Gist options
  • Save y-yu/a4c58f0d91f12b094c86 to your computer and use it in GitHub Desktop.
Save y-yu/a4c58f0d91f12b094c86 to your computer and use it in GitHub Desktop.
トランポリン化でStackOverflowの回避 ref: http://qiita.com/yyu/items/f1601749097ba3ee03db
Cons(1,Cons(2,Cons(3,Cons(4,Nil))))
def apply[A](as : A*) : List[A] = {
def loop(k : List[A] => List[A], xs : Seq[A]) : List[A] =
if (xs.isEmpty) k(Nil)
else loop(x => k(Cons(xs.head, x)), xs.tail)
loop(x => x, as)
}
def apply[A] (as : A*) : List[A] = {
def loop(k : List[A] => TailRec[List[A]], xs : Seq[A]) : TailRec[List[A]] =
if (xs.isEmpty) k(Nil)
else loop( x => Suspend(() => k(Cons(xs.head, x))), xs.tail)
loop( x => Return(x), as ).run
}
package fpinscala.datastructures
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head : A, tail : List[A]) extends List[A]
object List {
def apply[A](as : A*) : List[A] =
if (as.isEmpty) Nil
else Cons(as.head, apply(as.tail : _*))
}
package fpinscala.tailrec
sealed trait TailRec[A] {
final def run : A = this match {
case Return(v) => v
case Suspend(k) => k().run
}
}
case class Return[A](v : A) extends TailRec[A]
case class Suspend[A](resume : () => TailRec[A]) extends TailRec[A]
import fpinscala.datastructures.List
object TestList {
def main(args : Array[String]) : Unit = {
val xs = List(1, 2, 3, 4)
println(xs)
}
}
import fpinscala.datastructures.List
object TestListWithStackOverflow {
def main(args : Array[String]) : Unit = {
val xs = List( (1 to 10000).toSeq : _* )
println(xs)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment