作为练习的一部分,我正在编写一个API来生成随机数。
这是我的代码,我想测试notNegativeInt
函数。
我该怎么做?
(这里是完整的解决方案https://github.com/fpinscala/fpinscala/blob/master/answers/src/main/scala/fpinscala/state/State.scala)
import java.util.Random
object chapter6 {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
trait RNG {
def nextInt: (Int, RNG) // Should generate a random `Int`. We'll later define other functions in terms of `nextInt`.
}
object RNG {
// NB - this was called SimpleRNG in the book text
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL // `&` is bitwise AND. We use the current seed to generate a new seed.
val nextRNG = Simple(newSeed) // The next state, which is an `RNG` instance created from the new seed.
val n = (newSeed >>> 16).toInt // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
(n, nextRNG) // The return value is a tuple containing both a pseudo-random integer and the next `RNG` state.
}
}
// We need to be quite careful not to skew the generator.
// Since `Int.Minvalue` is 1 smaller than `-(Int.MaxValue)`,
// it suffices to increment the negative numbers by 1 and make them positive.
// This maps Int.MinValue to Int.MaxValue and -1 to 0.
def nonNegativeInt(rng: RNG): (Int, RNG) = {
val (i, r) = rng.nextInt
(if (i < 0) -(i + 1) else i, r)
}
}
}
答案 0 :(得分:1)
如果只想测试nonNegativeInt方法,可以提供RNG的模拟实现,它提供了在调用nextInt时要测试的值。 例如,nonNegativeInt中有2个可能的分支,因此您应该提供一个提供负数的RNG实例和另一个提供正数的实例。
class MyRNG(val num:Int) extends RNG {
self: RNG =>
def nextInt: (Int, RNG) = (num, this)
}
使用此RNG模拟,您可以测试您的nonNegativeInt方法,创建一个具有您想要测试的所需值的MyRNG。
对于这种特殊情况,您也可以省略自引用:
class MyRNG(val num:Int) extends RNG {
def nextInt: (Int, RNG) = (num, this)
}