如何从每个可能的字符生成字符串?

问题描述 投票:1回答:3

此刻,我正在生成这样的字符串:

arbStr :: Gen String
arbStr = listOf $ elements (alpha ++ digits)
  where alpha = ['a'..'z']
        digits = ['0'..'9']

但是很明显,这只能从字母数字字符生成字符串。我怎么做才能从所有可能的字符中生成?

haskell generator quickcheck
3个回答
3
投票

CharEnumBounded类型类的实例,可以使用arbitraryBoundedEnum :: (Bounded a, Enum a) => Gen a函数:

arbitraryBoundedEnum :: (Bounded a, Enum a) => Gen a

例如:

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" 类型类中使用arbitrary

Arbitrary Char

注意,import Test.QuickCheck(Gen, arbitrary, listOf) arbStr :: Gen String arbStr = listOf arbitrary arbitrary实现为使得ASCII字符比非ASCII字符普遍(三倍),因此“分布”不同。


1
投票

由于Char是Bounded以及Enum的一个实例(通过向GHCI询问Char来确认这一点,因此您可以简单地编写]]

:i Char

获取所有合法字符的列表。显然,这不会导致有效的随机访问!因此,您可以改为使用[minBound..maxBound] :: [Char] 将边界转换为Int,并使用QuickCheck的功能从整数范围中进行选择,然后使用Data.Char.ord :: Char -> Int映射回字符。

当我们喜欢时

Data.Chra.chr :: Int -> Char

我们得到所有字符的数量并说哇..!如果您认为列表太大,则可以总是喜欢λ> length ([minBound..maxBound] :: [Char]) 1114112 来限制范围。

因此,如果您需要drop x . take y许多随机字符,只需n列表,然后从经过改组的列表中进行shuffle :: [a] -> IO [a]

编辑:

当然,由于改组可能会很昂贵,因此,最好选择明智的策略。 randomly限制所有字符列表是理想的。就是

  1. 制作shuffle :: [a] -> IO [a]

  2. take n

  3. 最后从[[Item 2

    的结果中抽取limits = liftM sort . mapM randomRIO $ replicate 2 (0,1114112) :: (Ord a, Random a, Num a) => IO [a]像随机的limits >>= \[min,max] -> return . drop min . take max $ ([minBound..maxBound] :: [Char])一样,例如n

1
投票

当我们喜欢时

© www.soinside.com 2019 - 2024. All rights reserved.