Haskell 在保留种子的同时生成随机字符列表

Haskell 在保留种子的同时生成随机字符列表,haskell,Haskell,我的目标是编写一个函数,根据种子生成给定长度的随机字母数字字符串。重要的是,结果不仅是字符串,而且是新种子 我知道我可以通过使用take-on-randomRS获得一个字符串,但问题是我以后无法检索种子 generate :: StdGen -> String -> (String, StdGen) 我能够为一个字符编写它,尽管我无法获得同时允许字母和数字的范围 generateRandomCharacter gen = randomR ('a','z') gen 一种方法是将

我的目标是编写一个函数,根据种子生成给定长度的随机字母数字字符串。重要的是,结果不仅是字符串,而且是新种子

我知道我可以通过使用take-on-randomRS获得一个字符串,但问题是我以后无法检索种子

generate :: StdGen -> String -> (String, StdGen) 
我能够为一个字符编写它,尽管我无法获得同时允许字母和数字的范围

generateRandomCharacter gen = randomR ('a','z') gen

一种方法是将感兴趣的可用字符定义为数组,然后从数组中随机选择字符

randomEl :: RandomGen g => [a] -> g -> (a, g)
randomEl xs g -> (g', xs !! r) 
  where (r, g') = randomR (0, length xs - 1) g

randomAlphaNum :: RandomGen g => g -> (Char, g)
randomAlphaNum = randomEl (['0'..'9'] ++ ['a'..'z'])
下一步构建字符串应该很容易。。。例如,前奏曲中定义了

generate :: RandomGen g => Int -> g -> (String, g)
generate n g = (map fst iterations, (snd . last) iterations)
  where iterations = (take n . iterate (randomAlphaNum . snd)) (randomAlphaNum g)

一种方法是将感兴趣的可用字符定义为数组,然后从数组中随机选择字符

randomEl :: RandomGen g => [a] -> g -> (a, g)
randomEl xs g -> (g', xs !! r) 
  where (r, g') = randomR (0, length xs - 1) g

randomAlphaNum :: RandomGen g => g -> (Char, g)
randomAlphaNum = randomEl (['0'..'9'] ++ ['a'..'z'])
下一步构建字符串应该很容易。。。例如,前奏曲中定义了

generate :: RandomGen g => Int -> g -> (String, g)
generate n g = (map fst iterations, (snd . last) iterations)
  where iterations = (take n . iterate (randomAlphaNum . snd)) (randomAlphaNum g)

最好的方法是使用拆分:

class RandomGen g where
    split :: g -> (g,g)
    -- Other functions as well.
将随机生成器一分为二。使用其中一个结果生成随机字符串,并返回另一个结果

您的问题不清楚字符串应该有多长:大概它应该与输入字符串的长度相同。如果是这样,那么最好采用Int-length作为参数


你还说你还没有弄清楚如何从一个比“a”、“z”更复杂的范围中进行选择。你需要建立一个数组,或者更好的是,一个候选项向量,然后从中选择一个。您可以使用列表,但这意味着您每次都要遍历列表。

最好的方法是使用拆分:

class RandomGen g where
    split :: g -> (g,g)
    -- Other functions as well.
将随机生成器一分为二。使用其中一个结果生成随机字符串,并返回另一个结果

您的问题不清楚字符串应该有多长:大概它应该与输入字符串的长度相同。如果是这样,那么最好采用Int-length作为参数


你还说你还没有弄清楚如何从一个比“a”、“z”更复杂的范围中进行选择。你需要建立一个数组,或者更好的是,一个候选项向量,然后从中选择一个。您可以使用列表,但这意味着您每次都要遍历列表。

Paul Johnson的种子分割方法当然是合理的,但由于您正在生成一个已知长度的字符串,另一个好的选择是在随机性单子中使用replicateM

generateR :: (MonadRandom m, Random a) => Int -> (a, a) -> m [a]
generateR len range = replicateM len (getRandomR range)

Paul Johnson的种子分割方法当然是合理的,但由于您正在生成一个已知长度的字符串,另一个好的选择是在随机性单子中使用replicateM

generateR :: (MonadRandom m, Random a) => Int -> (a, a) -> m [a]
generateR len range = replicateM len (getRandomR range)

这是一个列表,不是数组。在其中查找东西会很慢。这是一个列表,而不是数组。在里面查找东西会很慢。