纯函数式状态编程:从随机数生成到通用状态处理
1. 副作用随机数生成的问题
在 Scala 中,标准库的 scala.util.Random 类可用于生成随机数,但其使用了副作用的方式。例如:
scala> val rng = new scala.util.Random
scala> rng.nextDouble
val res1: Double = 0.9867076608154569
scala> rng.nextDouble
val res2: Double = 0.8455696498024141
scala> rng.nextInt
val res3: Int = -623297295
scala> rng.nextInt(10)
val res4: Int = 4
由于每次调用方法时对象的内部状态会更新,这些方法不具有引用透明性,导致测试性、可组合性、模块化和并行性较差。以模拟掷骰子的方法为例:
def rollDie: Int =
val rng = new scala.util.Random
rng.nextInt(6)
此方法存在偏移错误,本应返回 1 到 6 之间的值,实际返回 0 到 5 之间的值。而且测试时,六分之五的情况下能通过,若测试失败也难以可靠重现。即使传入随机数生成器,也因难以保证其状态相同而无法解决问题。因此,应避免使用副作用。
超级会员免费看
订阅专栏 解锁全文
183

被折叠的 条评论
为什么被折叠?



