测试(“ok”)是由Noel Welsh和Dave Gurnell pag.254(“D.4更安全折叠使用Eval”)中的书“scala with cats”复制的 “),代码运行正常,这是trampolined foldRight
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)
}
测试(“ko”)为小列表返回相同的测试值(“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)
}
答案 0 :(得分:1)
这是@ OlegPyzhcov的评论,转换为社区wiki答案
您忘记L
中的0L
作为第二个参数传递给foldRightSafer
。
因此,调用的推断泛型类型是
foldRightSafer[Int, Int]((list : List[Int]), (0: Int))((_: Int) + (_: Int))
因此您的添加会溢出并为您提供小于2000000000(9个零,Int.MaxValue = 2147483647
)的内容。