Haskell生成具有适当性的随机数而没有显式递归

时间:2016-04-20 21:08:35

标签: 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将是我想要显示的第一个元素)然后我检查折叠中的适当性函数,如果它被尊重我将元素添加到累加器,但问题是程序块,因为我认为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)

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

1 个答案:

答案 0 :(得分:2)

右侧折叠可能更合适,例如:

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的调用。