加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

随机作为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可用于使用拒绝方法生成分布样本.
例如.这是创建beta分发样本生成器的代码:

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
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读