【问题标题】:List with random numbers in HaskellHaskell中的随机数列表
【发布时间】:2015-08-24 18:17:54
【问题描述】:

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

System.Random library
import System.IO

x = randomRIO (1,6::Int) 

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

【问题讨论】:

  • 请更详细地描述您目前所拥有的无法使用的内容。

标签: list haskell random


【解决方案1】:

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

test :: Int -> IO [Int]
test n = sequence $ replicate n $ randomRIO (1,6::Int)

【讨论】:

  • 然后我们就可以免费写了test = ($ randomRIO (1,6::Int)) . replicateM
【解决方案2】:

虽然 JP Moresmau 解决方案当然更可取,但您可能对更透明的解决方案感兴趣,该解决方案可以对 do 表示法和使用 IO 的递归函数有所了解:

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
  • 接下来它将使用randomList (n-1)递归生成一个n-1元素随机数列表并将其绑定到rs
  • 最后它再次使用returnr:rsn 元素列表)包装到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 的某些值上存在问题 - 能发现吗?如果是这样 - 您可以将函数更改为 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]

现在这已经完成(以稍微不同/更好的方式),您可以在Control.Monad 中找到它作为replicateM - 通过此导入,函数简化为:

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

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

有趣的事实 internally 这完全按照 JP 的回答来实现 ;)

【讨论】:

    【解决方案3】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      • 2015-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多