假设我想用蒙特卡罗模拟计算Pi作为练习.
我正在编写一个函数,它(0, 1), (1, 0)随机选取一个正方形中的一个点并测试该点是否在圆内.
import scala.math._
import scala.util.Random
def circleTest() = {
val (x, y) = (Random.nextDouble, Random.nextDouble)
sqrt(x*x + y*y) <= 1
}
Run Code Online (Sandbox Code Playgroud)
然后我正在编写一个函数,它将测试函数和试验次数作为参数,并返回测试结果为真的试验部分.
def monteCarlo(trials: Int, test: () => Boolean) =
(1 to trials).map(_ => if (test()) 1 else 0).sum * 1.0 / trials
Run Code Online (Sandbox Code Playgroud)
......我可以计算Pi
monteCarlo(100000, circleTest) * 4
Run Code Online (Sandbox Code Playgroud)
现在我想知道monteCarlo功能是否可以改进.你怎么写monteCarlo高效和可读?
例如,由于试验的数量很大,是否值得使用view或iterator代替Range(1, trials)而reduce代替map和sum?
这是我上一个问题的后续行动.我写了一个monad(用于练习)实际上是一个生成随机值的函数.但是,它未定义为类型类的实例scalaz.Monad.
现在我查看了Rng 库并注意到它定义Rng为scalaz.Monad:
implicit val RngMonad: Monad[Rng] =
new Monad[Rng] {
def bind[A, B](a: Rng[A])(f: A => Rng[B]) = a flatMap f
def point[A](a: => A) = insert(a)
}
Run Code Online (Sandbox Code Playgroud)
所以我想知道用户究竟是如何从中受益的.我们如何使用Rng类型类实例的事实scalaz.Monad?你能举一个例子吗?