【发布时间】:2015-08-04 20:33:05
【问题描述】:
《Scala 中的函数式编程》一书演示了一个纯函数式随机数生成器的示例,如下所示
trait RNG {
def nextInt: (Int, RNG)
}
object RNG {
def simple(seed: Long): RNG = new RNG {
def nextInt = {
val seed2 = (seed*0x5DEECE66DL + 0xBL) &
((1L << 48) - 1)
((seed2 >>> 16).asInstanceOf[Int],
simple(seed2))
}
}
}
用法看起来像
val (randomNumber,nextState) = rng.nextInt
我确实知道它是一个纯函数,因为它返回 下一个状态 并将其留在 API 客户端上,以便在下次需要随机数时使用它来调用 nextInt但我不明白的是'如何生成第一个随机数,因为我们必须至少提供一次seed。
是否应该有另一个函数来提升seed 以获得RNG?如果是这样,那么我们如何期望这个 API 的客户端知道它(因为在非功能实现中,用户只需调用 nextInt 并且状态由 API 维护)
谁能给出一个 Scala 中纯函数式随机数生成器的完整示例,并可能将其与一般的状态 Monad 联系起来。
【问题讨论】:
-
顺便说一句,如果你真的想学习纯函数式编程,你应该试试 Haskell。因为在 Haskell 中,如果不使用
IOmonad 或在更改状态时使用Statemonad,就无法引入副作用。即使您不每天使用它,对我来说它也是学习函数式编程的最佳语言。相反,Scala 过于宽松,在实际项目中使用可能会很好,但很难看出函数式世界和命令式世界之间的界限。 -
关于完全没有副作用,Haskell 背后的伟大思想家之一西蒙·佩顿·琼斯(Simon Peyton Jones)在这里说得很好:youtube.com/watch?v=iSmkqocn0oQ#t=3m17
标签: scala functional-programming monads state-monad