Haskell 如何从每个可能的字符中生成字符串?
目前,我正在生成如下字符串:Haskell 如何从每个可能的字符中生成字符串?,haskell,generator,quickcheck,Haskell,Generator,Quickcheck,目前,我正在生成如下字符串: arbStr :: Gen String arbStr = listOf $ elements (alpha ++ digits) where alpha = ['a'..'z'] digits = ['0'..'9'] 但显然,这只会从alpha num字符生成字符串。如何从所有可能的字符中生成呢?由于字符是有界和枚举的一个实例(通过向GHCI询问:I Char来确认这一点),您只需编写 [minBound..maxBound] :: [Ch
arbStr :: Gen String
arbStr = listOf $ elements (alpha ++ digits)
where alpha = ['a'..'z']
digits = ['0'..'9']
但显然,这只会从alpha num字符生成字符串。如何从所有可能的字符中生成呢?由于字符是有界和枚举的一个实例(通过向GHCI询问
:I Char
来确认这一点),您只需编写
[minBound..maxBound] :: [Char]
获取所有合法字符的列表。显然,这将不会导致有效的随机访问,虽然!因此,您可以使用
Data.Char.ord::Char->Int
将边界转换为Int
,并使用QuickCheck的功能从一系列整数中进行选择,然后映射回具有Data.Chra.chr::Int->Char
Char
的字符是Enum
和Bounded
类型类的实例,您可以使用以下函数:
import Test.QuickCheck(Gen, arbitraryBoundedEnum, listOf)
arbStr :: Gen String
arbStr = listOf arbitraryBoundedEnum
例如:
Prelude Test.QuickCheck> sample arbStr
""
""
"\821749"
"\433465\930384\375110\256215\894544"
"\431263\866378\313505\1069229\238290\882442"
""
"\126116\518750\861881\340014\42369\89768\1017349\590547\331782\974313\582098"
"\426281"
"\799929\592960\724287\1032975\364929\721969\560296\994687\762805\1070924\537634\492995\1079045\1079821"
"\496024\32639\969438\322614\332989\512797\447233\655608\278184\590725\102710\925060\74864\854859\312624\1087010\12444\251595"
"\682370\1089979\391815"
或者您可以使用任意字符
类型类中的任意
:
import Test.QuickCheck(Gen, arbitrary, listOf)
arbStr :: Gen String
arbStr = listOf arbitrary
请注意,Char
的arbitral
实现为ASCII字符比非ASCII字符更常见(三倍),因此“分布”是不同的。
λ> length ([minBound..maxBound] :: [Char])
1114112
我们得到所有角色的数量,然后说哇。。!如果您认为列表太大,那么您可能总是喜欢drop x。采用y
来限制范围
因此,如果您需要n
多个随机字符,只需选择列表,然后从该无序列表中选择n
编辑:
当然。。。因为洗牌可能很昂贵,所以我们最好选择一个聪明的策略。最好是随机限制所有字符列表。那就
limits=liftM排序。mapM randomRIO$replicate 2(0114112):(Ord a,Random a,Num a)=>IO[a]
限制>>=\[min,max]->返回。让我下车。取最大$([minBound..maxBound]:[Char])
n
many like randomChar
s likeliftM。从第2项的结果中取n
Char
已经是一个arbitral
实例,因此您可以只使用arbitral
方法。如果您需要字符串
,您也可以使用字符串
实例,该实例可通过该[]
实例获得。您能给出一个示例如何做到这一点吗?我有点纠结于代码的样子为什么第一个示例只返回斜杠和数字?还是那些ASCII码?@doctopus:这些只是unicode范围内的字符。由于它统一拾取字符,因此拾取的字符中有0.2%是ASCII字符,因为非ASCII字符的数量非常庞大。这就是为什么您可能希望使用任意
。