Search code examples
haskellgeneratorquickcheck

How to generate strings drawn from every possible character?


At the moment I'm generating strings like this:

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

But obviously this only generates strings from alpha num chars. How can I do it to generate from all possible chars?


Solution

  • Char is a instance of both the Enum and Bounded typeclass, you can make use of the arbitraryBoundedEnum :: (Bounded a, Enum a) => Gen a function:

    import Test.QuickCheck(Gen, arbitraryBoundedEnum, listOf)
    
    arbStr :: Gen String
    arbStr = listOf arbitraryBoundedEnum
    

    For example:

    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"
    

    Or you can make use of the arbitrary in the Arbitrary Char typeclass:

    import Test.QuickCheck(Gen, arbitrary, listOf)
    
    arbStr :: Gen String
    arbStr = listOf arbitrary
    

    Note that the arbitrary for Char is implemented such that ASCII characters are (three times) more common than non-ASCII characters, so the "distribution" is different.