【发布时间】:2015-08-06 12:03:20
【问题描述】:
我想通过使用 STArray 来实现局部突变效果和功能性随机数生成器来实现没有副作用的 Fisher-Yates 算法(就地数组洗牌)
type RNG[A] = State[Seed,A]
产生算法所需的随机整数。
我有一个方法 def intInRange(max: Int): RNG[Int] 可以用来在 [0,max) 中生成随机的 Int。
来自Wikipedia:
To shuffle an array a of n elements (indices 0..n-1): for i from n − 1 downto 1 do j ← random integer such that 0 ≤ j ≤ i exchange a[j] and a[i]
我想我需要以某种方式将State 与ST 堆叠起来,但这让我感到困惑。我需要[S]StateT[ST[S,?],Seed,A] 吗?我是否也必须重写RNG 才能使用StateT?
(编辑)我不想涉及IO,也不想用Vector 代替STArray,因为不会就地执行随机播放。
我知道有一个 Haskell 实现 here,但我目前无法理解并将其移植到 Scalaz。但也许你可以? :)
提前致谢。
【问题讨论】:
-
您要避免的副作用到底是什么?我对 Scala 知之甚少,但至少在 MT 环境中你必须锁定
i并修改序列本身(你正在交换 a_i 和 a_j) -
我不确定您要做什么。使用递归交换元素很简单。要获得没有副作用的随机数,您的 RNG 可以有一个 map 函数,该函数使用随机数而不是
getNext...方法调用其一阶函数
标签: scalaz state-monad st-monad starray scala-cats