[英]List with random numbers in Haskell
I want to generate a list with random numbers in Haskell. 我想在Haskell中生成一个包含随机数的列表。 I have to use the import System.Random library.
我必须使用import System.Random库。 I started doing something like that but it doesn't work.
我开始做类似的事情,但它不起作用。 I have to create a list with N positions, and all these positions must have random numbers.
我必须创建一个包含N个位置的列表,并且所有这些位置必须具有随机数。 Thanks!
谢谢!
System.Random library
import System.IO
x = randomRIO (1,6::Int)
test :: IO Int
test = randomRIO (1,6::Int)
You need to run randomRIO
n times. 你需要运行
randomRIO
n次。 For this you can use replicate
. 为此,您可以使用
replicate
。 This will give you a list of monadic values, that you can transform into a monadic list of values with sequence
: 这将为您提供一个monadic值列表,您可以将其转换为带
sequence
的monadic值列表:
test :: Int -> IO [Int]
test n = sequence $ replicate n $ randomRIO (1,6::Int)
While JP Moresmau solution is certainly preferable, you might be interested in a more transparent solution that shines some light on the do
notation and recursive functions using IO
: 虽然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)
you should note the following: 你应该注意以下几点:
n == 0
the function will use return
to wrap the empty list into IO
and return this n == 0
该函数将使用return
将空列表包装到IO
并返回此值 do
body it will first generate a random number r
using randomRIO
do
主体内部,它将首先使用randomRIO
生成随机数r
n-1
element list of random numbers using randomList (n-1)
and bind it to rs
randomList (n-1)
以递归方式生成随机数的n-1
元素列表,并将其绑定到rs
return
again to wrap r:rs
(a n
element list) into IO
and return it return
将r:rs
(一个n
元素列表)包装到IO
并返回它 here is an example in GHCi : 这是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]
seems random enough 似乎随机
the function has a problem with certain values of n
- can you spot it? 该函数有一定的
n
值问题 - 你能发现它吗? And if so - can you change the function to be total ? 如果是这样的话 - 你可以将功能改为总数吗?
If you look closely you see that you can pull out randomRIO (1,6) :: IO Int
there like this: 如果你仔细观察,你会看到你可以像这样拉出
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)
which of course you would have to use like this: 当然你必须使用这样的:
λ> mList 10 $ randomRIO (1,6)
[2,2,2,5,5,1,3,6,6,1]
now this has been done before (in a slightly different/better) way and you can find it as replicateM
in Control.Monad
- with this import the function simplifies to: 现在这已经完成了(以稍微不同/更好)的方式,你可以在
Control.Monad
找到它作为replicateM
- 通过这个导入,该函数简化为:
import System.Random (randomRIO)
import Control.Monad (replicateM)
randomList :: Int -> IO([Int])
randomList n = replicateM n $ randomRIO (1,6)
fun fact internally this is implemented exactly as what JP answered ;) 内部 有趣的事实,这与JP回答的完全相同;)
Using only one generator and infinite list 仅使用一个生成器和无限列表
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.