Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Created May 20, 2012 03:03
Show Gist options
  • Save gakuzzzz/2737698 to your computer and use it in GitHub Desktop.
Save gakuzzzz/2737698 to your computer and use it in GitHub Desktop.
中断可能なfold
sealed trait FoldResult[+A]
case class Continue[+A](a: A) extends FoldResult[A]
case class End[+A](a: A) extends FoldResult[A]
class LimitFoldable[+A](underlying: Traversable[A]) {
def limitFoldLeft[B](init: B)(f: (B, A) => FoldResult[B]): B = {
@tailrec
def fold(sentinel: B, rest: Traversable[A]): B = {
if (rest.isEmpty) return sentinel
f(sentinel, rest.head) match {
case End(e) => e
case Continue(e) => fold(e, rest.tail)
}
}
fold(init, underlying)
}
}
implicit def traversableToLimitFoldable[A](underlying: Traversable[A]) =
new LimitFoldable(underlying)
scala> List(1, 2, 3, 4, 5, 6, 7).limitFoldLeft(0) {
| case (a, b) => if (a > 10) End(a) else Continue(a+b)
| }
res0: Int = 15
scala> List(1, 2, 3, 4, 5, 6, 7).limitFoldLeft(0) {
| case (a, b) => if (a > 1000) End(a) else Continue(a+b)
| }
res1: Int = 28
@gakuzzzz
Copy link
Author

なるほど継続モナド!まさしくこの用途にぴったりですね。
ってことは限定継続つかえばスタックオーバーフローの問題も解決できるんですかね?

ContinuationモナドとFreeモナドの関係は僕もぜんぜん理解できてませんorz
というか僕の継続モナドの理解も怪しい気がしてきました><
このコードじっくり読んで勉強させてもらいます!ありがとうございます!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment