Haskell 无需显式递归即可生成随机数

标签 haskell

这里我有一个函数来生成 0 到 999 之间的随机数流。

randomHelp :: RandomGen g => g -> [Int]
randomHelp g = zipWith (mod) (map fst $ iterate (next . snd) $ next $ snd $ split g) $ repeat 1000

我想从上面定义的流中选择所有数字,并且每个 elem(i)elem(i + 1) 必须遵守某种属性。例如,他们的 gcd 必须是 1。我能想到的只是一个折叠函数,因为我可以从包含数字 1 的累加器开始(假设 1 将是我想要显示的第一个元素),然后我检查折叠函数的适当性,如果它受到尊重,我添加元素到累加器,但问题是程序由于 stackoverflow 而阻塞,我认为。

这是函数:

randomFunc :: RandomGen g => g -> [Int]
randomFunc g = foldl (\acc x -> if (gcd x (last acc) == 1) then acc ++ [x] else acc) [1] (randomHelp g)

注意:我不想使用显式递归。

最佳答案

正确的折叠可能会更合适,例如:

import System.Random (RandomGen, randomRs, mkStdGen)

randomFunc :: RandomGen g => g -> [Int]
randomFunc g = foldr go (const []) (randomRs (1, 20) g) 1
    where go x f lst = if gcd x lst == 1 then x: f x else f lst

然后

\> take 20 . randomFunc $ mkStdGen 1
[16,7,6,19,8,15,16,1,9,2,15,17,14,3,11,17,15,8,1,5]

这样做,您可以使用 : 构建列表而不是++这可能会导致二次性能成本,并且您可以绕过对 last 的调用.

关于Haskell 无需显式递归即可生成随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36755220/

相关文章:

haskell - 如何在 Haskell Data.Tree 中找到节点的路径

haskell - 指针的编码向量

haskell - 在 Haskell CIS194 第 2 周练习 2 中使用匿名函数

haskell - Haskell 中的函数依赖

haskell - 定义 Haskell 类型构造函数相等?

haskell - 递归内存

haskell - 匹配参数类型的特定类型

haskell - corecursion 和 codata

haskell - 为什么我们要在FRP中使用Behavior

arrays - 有效地迭代 Haskell 中多个数组/列表的前缀