如果没有范围内的IO,如何在Haskell中生成随机数?
我想生成一个范围内的随机数,类型签名为如果没有范围内的IO,如何在Haskell中生成随机数?,haskell,random,Haskell,Random,我想生成一个范围内的随机数,类型签名为Int->Int。我读过多篇其他文章,但没有一篇建议返回类型Int。我在代码中使用了System.IO.Unsafe,但不建议这样做。这是我的密码: import System.IO.Unsafe -- random number generator rng :: Int -> Int rng upper = unsafePerformIO $ randomRIO (0,upper-1) 有人对如何在Haskell中生成范围内的随机整数有什么建议
Int->Int
。我读过多篇其他文章,但没有一篇建议返回类型Int
。我在代码中使用了System.IO.Unsafe
,但不建议这样做。这是我的密码:
import System.IO.Unsafe
-- random number generator
rng :: Int -> Int
rng upper = unsafePerformIO $ randomRIO (0,upper-1)
有人对如何在Haskell中生成范围内的随机整数有什么建议吗
编辑:可能无法更改IO Int->Int
,因此我将代码转换为
-- random number generator
rng :: Int -> IO Int
rng upper = randomRIO (0,upper-1)
我之所以需要一个rng,是因为我想获取列表长度范围内的随机数,以获取列表元素的索引
列表!!rng(长度列表)
但我发现错误无法将预期的类型“Int”与预期的实际类型“IO Int”匹配
它不是重复的,因为1。我希望值在2的范围内。我的rng不返回相同的值。我是哈斯克尔的新手,我不知道如何操纵单子。感谢您的帮助。Haskell不是为了在不使用IO的情况下生成随机数而构建的
您的示例,list!!rng(长度列表)
,不起作用,因为rng
返回IO Int
和代码>需要一个Int
下面是一个使用rng
函数从列表中获取随机元素的函数:
-- Will crash on empty list
randomElementFromList :: [a] -> IO a
randomElementFromList list = do
r <- rng (length list)
return $ list !! r
--将在空列表上崩溃
randomElementFromList::[a]->IO a
randomElementFromList=do
rI本着的精神,这里有一个没有任何IO的“解决方案”:
rng :: Int -> Int
rng upper
| upper<=4 = upper
| otherwise = 4
…或者,您可以显式地将更新的状态与结果一起传递
rng'' :: Int -> RandStV -> (RandStV, Int)
rng'' upper x =
let x' = ((x * 1103515245) + 12345) `mod` 0x7fffffff
in (x', x `mod` upper)
…或者它可以通过专用的方式传递,这只是编写更新变量传递的另一种方式:
type RandStM = State RandStV
rng''' :: Int -> RandStM Int
rng''' upper = do
x <- get
let x' = ((x * 1103515245) + 12345) `mod` 0x7fffffff
put x'
return $ x `mod` upper
类型RandStM=状态RandStV
rng“”::Int->RandStM Int
rng''上限=do
你不能理智地把它变成Int->Int
。你能得到的最接近并且仍然表现得理智的是Int->StdGen->(StdGen,Int)
;此类型可以使用randomR
而不是randomRIO
实现。可能重复rng x=fst$randomR(0,x-1)$makeStdGen$length“https://xkcd.com/221“
:p您不需要涉及IO,但由于Haskell引用的透明性,您不能拥有Int->Int
类型签名。”。没有理由将此指定为[Int]
randomElementFromList::[a]->IO a
当然还有模式do{x
type RandStM = State RandStV
rng''' :: Int -> RandStM Int
rng''' upper = do
x <- get
let x' = ((x * 1103515245) + 12345) `mod` 0x7fffffff
put x'
return $ x `mod` upper