如何在Scala中返回函数

如何 在Scala中返回函数 副作用词法闭包1?


例如,我在Go中查看此代码示例:


...    

// fib returns a function that returns

// successive Fibonacci numbers.

func fib() func() int {

    a, b := 0, 1

    return func() int {

        a, b = b, a+b

        return b

    }

}

...

println(f(), f(), f(), f(), f())

打印1 2 3 5 8


而且我不知道如何在Scala中编写相同的内容。


万千封印
浏览 226回答 3
3回答

慕尼黑的夜晚无繁华

稍短一些,您不需要退货。def fib() = {    var a = 0    var b = 1    () => {         val t = a;        a = b        b = t + b        b    }}

ibeautiful

加!可变变量?!val fib: Stream[Int] =&nbsp; 1 #:: 1 #:: (fib zip fib.tail map Function.tupled(_+_))您可以返回获取第n个fib的文字函数,例如:val fibAt: Int => Int = fib drop _ head编辑:由于您要求“每次调用f都会获得不同的值”的功能性方法,因此,您将按照以下方法进行操作。这使用了Scalaz的Statemonad:import scalaz._import Scalaz._def uncons[A](s: Stream[A]) = (s.tail, s.head)val f = state(uncons[Int])该值f是状态转换函数。给定一条流,它将返回其头部,并通过使其尾部对流进行“变异”。请注意,这f是完全可以忽略的fib。这是一个REPL会话,说明了它是如何工作的:scala> (for { _ <- f; _ <- f; _ <- f; _ <- f; x <- f } yield x)res29: scalaz.State[scala.collection.immutable.Stream[Int],Int] = scalaz.States$$anon$1@d53513scala> (for { _ <- f; _ <- f; _ <- f; x <- f } yield x)res30: scalaz.State[scala.collection.immutable.Stream[Int],Int]&nbsp; = scalaz.States$$anon$1@1ad0ff8scala> res29 ! fibres31: Int = 5scala> res30 ! fibres32: Int = 3显然,获得的价值取决于调用的次数f。但这全是纯功能性的,因此是模块化且可组合的。例如,我们可以传递任何非空流,而不仅仅是fib。因此,您可以看到没有副作用的效果。

九州编程

尽管我们共享的斐波那契函数很酷的实现仅与问题有切线关系,但这里是一个简要记录的版本:val fib: Int => BigInt = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;def fibRec(f: Int => BigInt)(n: Int): BigInt = {&nbsp; &nbsp; &nbsp; if (n == 0) 1&nbsp;&nbsp; &nbsp; &nbsp; else if (n == 1) 1&nbsp;&nbsp; &nbsp; &nbsp; else (f(n-1) + f(n-2))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;Memoize.Y(fibRec)}它使用实现该问题的答案的记忆定点组合器:在Scala 2.8中,用于存储内存可变数据表的类型是什么?顺便说一下,组合器的实现提出了一种稍微更明确的技术,用于实现函数副作用词法闭包:def fib(): () => Int = {&nbsp; &nbsp;var a = 0&nbsp; &nbsp;var b = 1&nbsp; &nbsp;def f(): Int = {&nbsp; &nbsp; &nbsp; val t = a;&nbsp; &nbsp; &nbsp; a = b&nbsp; &nbsp; &nbsp; b = t + b&nbsp; &nbsp; &nbsp; b&nbsp; }&nbsp; f}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go