我希望在Haskell中生成一个包含随机数的列表。我需要使用导入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)
test = ($ randomRIO (1,6::Int)) . replicateM
- madnight虽然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)
请注意以下内容:
n == 0
,该函数将使用return
将空列表包装成IO
并返回它do
体内,它将首先使用randomRIO
生成一个随机数r
n-1
个随机数元素组成的列表,并将其绑定到rs
return
将r:rs
(一个n
元素列表)包装成IO
并返回它这是在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]
看起来足够随机
该函数在某些n
的值上存在问题 - 你能发现吗?如果可以,你能将函数改为完美吗?
如果你仔细观察,就会发现可以像这样提取出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]
现在这个功能已经被实现了(以稍微不同/更好的方式),你可以在Control.Monad
中找到它的实现,通过引入该模块,该函数变得更加简单:
import System.Random (randomRIO)
import Control.Monad (replicateM)
randomList :: Int -> IO([Int])
randomList n = replicateM n $ randomRIO (1,6)
趣闻 内部实现与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