【发布时间】:2018-04-14 20:36:09
【问题描述】:
所以我正在关注http://jelv.is/blog/Lazy-Dynamic-Programming/ 并在 Scala 中实现斐波那契示例。这是我的实现:
class Lazy[T] (expr : => T) {
lazy val value = expr
def apply(): T = value
}
object Lazy{ def apply[T](expr : => T) = new Lazy({expr}) }
def fib(n: Int): Int = {
def doFib(i: Int): Lazy[Int] = Lazy {
if (i <= 2) 1
else fibs(i - 1)() + fibs(i - 2)()
}
lazy val fibs = Array.tabulate[Lazy[Int]](n)(doFib)
doFib(n).value
}
fib(5)
在这种情况下,fib(5) 正确返回结果 5。
然后我想看看Lazy[T]是否可以通过尝试以下代码变成monad,这会导致StackOverflow运行时错误:
class Lazy[T] (expr : => T) {
lazy val value = expr
def apply(): T = value
def flatMap[A](f: T => Lazy[A]): Lazy[A] = Lazy { f(value).value }
def map[A](f: T => A): Lazy[A] = Lazy { f(value) }
}
object Lazy{ def apply[T](expr : => T) = new Lazy({expr}) }
def fib(n: Int): Int = {
def doFib(i: Int): Lazy[Int] =
if (i <= 2) Lazy(1)
else for {
a <- fibs(i - 1)
b <- fibs(i - 2)
} yield a + b
lazy val fibs = Array.tabulate[Lazy[Int]](n)(doFib)
doFib(n).value
}
fib(5)
似乎 fibs(i - 1) 计算得太早,导致无限递归。不知道有没有for的理解语法相当于第一个代码sn-p?
【问题讨论】:
标签: scala dynamic-programming lazy-evaluation