QuickCheck - Haskell (генерирует случайную строковую дату) - PullRequest
0 голосов
/ 30 августа 2018

Мне нужно сгенерировать строку имен-дат, разделенных пробелами, где имя - это просто произвольная длина символов, а дата - всего 4 цифры. Например:

"dfghjkl-1234 derftgyhjuik-5678"

Теперь у меня есть это решение:

genArgs :: Gen String
genArgs = do
  cs <- listOf1 genCourse
  return (unwords cs)

genCourse :: Gen String
genCourse = do
  ns <- elements ["1111","1234","4567","1411","1284","4517"]
  ls <- listOf1 $ elements ['a'..'z']
  return (ls ++ "-" ++ ns)

Но мне пришлось жестко кодировать в списке чисел, потому что некоторые из них должны повторяться (иметь одинаковые числа), и если бы я просто выбрал их случайным образом, было бы очень маловероятно иметь что-то вроде:

"dfghjkl-1234 derftgyhjuik-5678 gyhujik-1234"

когда-нибудь случится. Я хотел бы сгенерировать случайное 4-значное число, а затем некоторые элементы этой строки должны иметь такое повторение, скажем, 25% времени. Я полагаю, что это достигается с частотой?

1 Ответ

0 голосов
/ 04 сентября 2018

Вот одна попытка. Вы можете начать с определения генератора этих четырехзначных «дат»:

genDate :: Gen String
genDate = vectorOf 4 $ elements ['0'..'9']

Далее, функция, которая с учетом String вернет генератор «курсов»:

genCourse :: String -> Gen String
genCourse ns = do
  ls <- listOf1 $ elements ['a'..'z']
  return (ls ++ "-" ++ ns)

Чтобы реализовать функцию genArgs, одним из способов удовлетворения требования может быть сначала сгенерировать один date, а затем использовать frequency, чтобы либо вернуть это случайно сгенерированное значение, либо другие случайно сгенерированные даты:

genArgs :: Gen String
genArgs = do
  date <- genDate
  dates <- listOf1 $ frequency [(1, return date), (3, genDate)]
  courses <- traverse genCourse dates
  return $ unwords courses

Одно из четырех значений будет сгенерировано генератором констант return date, а три из четырех будут сгенерированы случайным образом с помощью genDate.

В результате получается список строк «date», которые затем можно просмотреть с помощью genCourse.

Вот несколько примеров значений:

*Main Lib> sample genArgs
"u-8747"
"sd-2575 l-3069"
"rfn-1191 jbs-8962 kjtt-1909"
"ezbtrj-6167 t-3474 daaht-0834 puc-2266"
"epkbtz-8334 uj-8829 etu-9061 wkkro-5514 fque-4639 vgct-4572 daczohr-8683 zomo-5789"
"mkrnvyrjfu-6765 vunu-6869 xjd-1135 rkritwi-6869 odmvxec-4236 mirrfp-1715 jccla-0998 qyasxozuq-3713"
"cvyxjnvrqao-3675 rzsnkqplbv-3675 b-3675 ekchdgksbk-6463 nonz-3354 ue-3675 mwwoovthxusd-8882"
"vwffdntpwawo-4565"
"t-0278 dyauqxenubxjohr-7815 yvogox-5183 oz-4660 eufwzgabvo-3813 azetihbmuw-8622 tizuzbmacv-6102 tzqjz-9686 jsaaepngbi-7394 fzzpzykibohzf-7394 muhlolo-6770 tixpoi-7394 kqhvvw-5877 ulg-7394 ce-6817"
"y-3550 tfakitqwrhyrpu-6923 gwzpegkpxjn-7222 jkvuwsf-2819 il-2268 sfmxdh-0004 vqmalaisvtqtg-1759 acxn-3146 fuhwps-4534 rtqgqzndtjhiygan-3326 yktgeeww-2819 irtrpnh-0198 ghqs-2819 lofyzpejuzw-8408 hd-2647"
"kts-8877 kipbbttkzvopwkrmemsz-2158 xqblwsgdrhaupbfgg-0841 eminvqkvwl-9193 bjhzmafgnjyhdzuppar-9912 cg-7737 enjvjalpkstizymci-0039"

Обратите внимание, что, например, 6869 повторяется дважды в шестом значении, а 3675 повторяется четыре раза в седьмом примере.

...