3 回答

TA貢獻(xiàn)1864條經(jīng)驗(yàn) 獲得超6個(gè)贊
稍短一些,您不需要退貨。
def fib() = {
var a = 0
var b = 1
() => {
val t = a;
a = b
b = t + b
b
}
}

TA貢獻(xiàn)1993條經(jīng)驗(yàn) 獲得超6個(gè)贊
加!可變變量?!
val fib: Stream[Int] =
1 #:: 1 #:: (fib zip fib.tail map Function.tupled(_+_))
您可以返回獲取第n個(gè)fib的文字函數(shù),例如:
val fibAt: Int => Int = fib drop _ head
編輯:由于您要求“每次調(diào)用f都會獲得不同的值”的功能性方法,因此,您將按照以下方法進(jìn)行操作。這使用了Scalaz的Statemonad:
import scalaz._
import Scalaz._
def uncons[A](s: Stream[A]) = (s.tail, s.head)
val f = state(uncons[Int])
該值f是狀態(tài)轉(zhuǎn)換函數(shù)。給定一條流,它將返回其頭部,并通過使其尾部對流進(jìn)行“變異”。請注意,這f是完全可以忽略的fib。這是一個(gè)REPL會話,說明了它是如何工作的:
scala> (for { _ <- f; _ <- f; _ <- f; _ <- f; x <- f } yield x)
res29: scalaz.State[scala.collection.immutable.Stream[Int],Int] = scalaz.States$$anon$1@d53513
scala> (for { _ <- f; _ <- f; _ <- f; x <- f } yield x)
res30: scalaz.State[scala.collection.immutable.Stream[Int],Int] = scalaz.States$$anon$1@1ad0ff8
scala> res29 ! fib
res31: Int = 5
scala> res30 ! fib
res32: Int = 3
顯然,獲得的價(jià)值取決于調(diào)用的次數(shù)f。但這全是純功能性的,因此是模塊化且可組合的。例如,我們可以傳遞任何非空流,而不僅僅是fib。
因此,您可以看到?jīng)]有副作用的效果。

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超4個(gè)贊
盡管我們共享的斐波那契函數(shù)很酷的實(shí)現(xiàn)僅與問題有切線關(guān)系,但這里是一個(gè)簡要記錄的版本:
val fib: Int => BigInt = {
def fibRec(f: Int => BigInt)(n: Int): BigInt = {
if (n == 0) 1
else if (n == 1) 1
else (f(n-1) + f(n-2))
}
Memoize.Y(fibRec)
}
它使用實(shí)現(xiàn)該問題的答案的記憶定點(diǎn)組合器:在Scala 2.8中,用于存儲內(nèi)存可變數(shù)據(jù)表的類型是什么?
順便說一下,組合器的實(shí)現(xiàn)提出了一種稍微更明確的技術(shù),用于實(shí)現(xiàn)函數(shù)副作用詞法閉包:
def fib(): () => Int = {
var a = 0
var b = 1
def f(): Int = {
val t = a;
a = b
b = t + b
b
}
f
}
- 3 回答
- 0 關(guān)注
- 260 瀏覽
添加回答
舉報(bào)