[英]Scala cats trampoline
測試(“ok”)是從 Noel Welsh 和 Dave Gurnell pag.254(“D.4 Safer Folding using Eval”)的“scala with cat”一書中復制的,代碼運行良好,這是蹦床折疊對
import cats.Eval
test("ok") {
val list = (1 to 100000).toList
def foldRightEval[A, B](as: List[A], acc: Eval[B])(fn: (A, Eval[B]) => Eval[B]): Eval[B] =
as match {
case head :: tail =>
Eval.defer(fn(head, foldRightEval(tail, acc)(fn)))
case Nil =>
acc
}
def foldRight[A, B](as: List[A], acc: B)(fn: (A, B) => B): B =
foldRightEval(as, Eval.now(acc)) { (a, b) =>
b.map(fn(a, _))
}.value
val res = foldRight(list, 0L)(_ + _)
assert(res == 5000050000l)
}
test("ko") 為小列表返回相同的 test("ok") 值,但對於長列表,該值不同。 為什么?
test("ko") {
val list = (1 to 100000).toList
def foldRightSafer[A, B](as: List[A], acc: B)(fn: (A, B) => B): Eval[B] = as match {
case head :: tail =>
Eval.defer(foldRightSafer(tail, acc)(fn)).map(fn(head, _))
case Nil => Eval.now(acc)
}
val res = foldRightSafer(list, 0)((a, b) => a + b).value
assert(res == 5000050000l)
}
這是@OlegPyzhcov 的評論,已轉換為社區維基答案
您忘記了0L
的L
作為第二個參數傳遞給foldRightSafer
。 因此,調用的推斷泛型類型是
foldRightSafer[Int, Int]((list : List[Int]), (0: Int))((_: Int) + (_: Int))
所以你的加法溢出並給你小於 2000000000 (9 個零, Int.MaxValue = 2147483647
)的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.