随机作为scalaz.Monad的实例
发布时间:2020-12-16 08:58:42 所属栏目:安全 来源:网络整理
导读:这是我之前的 question的后续内容.我写了一个monad(用于练习),它实际上是一个生成随机值的函数.但是,它未定义为类型类scalaz.Monad的实例. 现在我看了Rng library并注意到它将Rng定义为scalaz.Monad: implicit val RngMonad: Monad[Rng] = new Monad[Rng] {
这是我之前的
question的后续内容.我写了一个monad(用于练习),它实际上是一个生成随机值的函数.但是,它未定义为类型类scalaz.Monad的实例.
现在我看了Rng library并注意到它将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) } 所以我想知道用户究竟是如何从中受益的.我们怎样才能使用Rng是类型类scalaz.Monad的实例?你能举一个例子吗? 解决方法
其中一个好处是,您将获得MonadOps中定义的许多有用方法.
例如,Rng.double.iterateUntil(_< 0.1)将仅生成小于0.1的值(而将跳过大于0.1的值). iterateUntil可用于使用拒绝方法生成分布样本. import com.nicta.rng.Rng import java.lang.Math import scalaz.syntax.monad._ object Main extends App { def beta(alpha: Double,beta: Double): Rng[Double] = { // Purely functional port of Numpy's beta generator: https://github.com/numpy/numpy/blob/31b94e85a99db998bd6156d2b800386973fef3e1/numpy/random/mtrand/distributions.c#L187 if (alpha <= 1.0 && beta <= 1.0) { val rng: Rng[Double] = Rng.double val xy: Rng[(Double,Double)] = for { u <- rng v <- rng } yield (Math.pow(u,1 / alpha),Math.pow(v,1 / beta)) xy.iterateUntil { case (x,y) => x + y <= 1.0 }.map { case (x,y) => x / (x + y) } } else ??? } val rng: Rng[List[Double]] = beta(0.5,0.5).fill(10) println(rng.run.unsafePerformIO) // Prints 10 samples of the beta distribution } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |