繁体   English   中英

斯卡拉猫蹦床

[英]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 的评论,已转换为社区维基答案

您忘记了0LL作为第二个参数传递给foldRightSafer 因此,调用的推断泛型类型是

foldRightSafer[Int, Int]((list : List[Int]), (0: Int))((_: Int) + (_: Int))

所以你的加法溢出并给你小于 2000000000 (9 个零, Int.MaxValue = 2147483647 )的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM