考虑从一组可能的字符串中生成字符串的问题,这样一旦选择字符串,就不能再次重复。对于这个任务,我想使用QuickCheck
的Gen
函数。使用QuickCheck从字符串池中生成随机字符串
如果我看看我正在编写的函数的类型,它看起来非常像状态monad。由于我正在使用另一个monad,即Gen
,在州monad中。我使用StateT
写了我的第一次尝试。
arbitraryStringS :: StateT GenState Gen String
arbitraryStringS =
mapStateT stringGenS get
其中:
newtype GenState = St {getStrings :: [String]}
deriving (Show)
removeString :: String -> GenState -> GenState
removeString str (St xs) = St $ delete str xs
stringGenS :: Gen (a, GenState) -> Gen (String, GenState)
stringGenS genStSt =
genStSt >>= \(_, st) ->
elements (getStrings st) >>= \str ->
return (str, removeString str st)
东西困扰我的这个实现是我不使用的stringGenS
第一个元素的事实。其次,我的最终目标是为JSON值定义一个随机生成器,它使用资源池(不仅包含字符串)。使用StateT
促使我实现QuickCheck
的elements
,listOf
等
我想知道是否有实现这一目标的一个更好的办法,或者这样的复杂性是与生俱来的,以确定现有的单子的状态变量的“状态”的变种。
我会以另一种方式来做 - 存储创建的“字符串” - 或者至少是种子,并比较每个种子/生成的字符串以获得种子/字符串的“集合”中的成员资格。 – epsilonhalbe
另一种选择是使用uuid来生成“最可能”唯一的字符串,如果您只有一组有限的字符串 - 最终用完字符串,可以通过组合大型基本组来解决 - 但仍然可以运行到重复的字符串 - 如果你需要“真正的唯一性”,我会去一个基本集合+像自然数字这样的无限集合并结合。 – epsilonhalbe
字符串来自资源池很重要。这可用于使用某些数据库中存在的数据生成测试。 –