Haskell 中的随机数列表

List with random numbers in Haskell

我想在 Haskell 中生成一个包含随机数的列表。我必须使用 import System.Random 库。我开始做类似的事情,但它不起作用。我必须创建一个包含 N 个位置的列表,所有这些位置都必须有随机数。谢谢!

System.Random library
import System.IO

x = randomRIO (1,6::Int) 

test :: IO Int
test = randomRIO (1,6::Int)

您需要 运行 randomRIO n 次。为此,您可以使用 replicate。这将为您提供一元值列表,您可以使用 sequence:

将其转换为一元值列表
test :: Int -> IO [Int]
test n = sequence $ replicate n $ randomRIO (1,6::Int)

虽然 JP Moresmau 解决方案当然更可取,但您可能对更透明的解决方案感兴趣,该解决方案使用 IO:

阐明了 do 符号和递归函数
import System.Random (randomRIO)

randomList :: Int -> IO([Int])
randomList 0 = return []
randomList n = do
  r  <- randomRIO (1,6)
  rs <- randomList (n-1)
  return (r:rs) 

您应该注意以下几点:

  • if n == 0 函数将使用 return 将空列表包装成 IO 和 return this
  • else 在 do 正文中,它将首先使用 randomRIO
  • 生成一个随机数 r
  • 接下来它将使用randomList (n-1)递归生成一个n-1随机数元素列表并将其绑定到rs
  • 最后它再次使用 returnr:rs(一个 n 元素列表)包装到 IO 和 return 中

这是 GHCi 中的示例:

λ> randomList 10
[2,4,4,5,2,2,2,5,6,2]

λ> randomList 10
[2,4,4,2,5,2,6,3,4,1]

看起来很随意

remarks/exercise:

该函数对 n 的某些值有问题 - 能发现吗?如果是这样 - 你可以将函数更改为 total?

玩得开心

如果你仔细观察,你会发现你可以像这样拉出 randomRIO (1,6) :: IO Int

mList :: Int -> IO a -> IO([a])
mList 0 gen = return []
mList n gen = do
  r  <- gen
  rs <- mList(n-1) gen
  return (r:rs) 

当然你必须像这样使用:

λ> mList 10 $ randomRIO (1,6)
[2,2,2,5,5,1,3,6,6,1]

现在这已经完成了(稍微 different/better),你可以在 Control.Monad 中找到它作为 replicateM - 通过这个导入函数简化为:

import System.Random (randomRIO)
import Control.Monad (replicateM)

randomList :: Int -> IO([Int])
randomList n = replicateM n $ randomRIO (1,6)

有趣的事实 internally 这与 JP 回答的完全一样;)

只使用一个生成器和无限列表

import Data.List
import System.Random

randomList :: (Int, Int) -> IO [Int]
randomList interval =
  newStdGen >>= return . unfoldr (Just . randomR interval)

main :: IO ()
main = do
  ls <- randomList (1, 6)
  putStrLn $ show $ take 4 ls