module Test.QuickCheck.Instances.Char
       (nonSpace,whitespace,space,newline
       ,lowerAlpha,upperAlpha,numeric
       ,parenthesis,bracket,brace
       ,operator
       ) where

import Data.Char
import Test.QuickCheck
import Test.QuickCheck.Instances.Eq

-- instance Arbitrary Char where
--     arbitrary   = choose ('\0','\255')
--     coarbitrary = variant . ord

-- instance Arbitrary Char where
--     arbitrary   = choose ('\0','\255')

-- instance CoArbitrary Char where
--     coarbitrary = variant . ord

-- Bob: why the `rem` 4 ?

{- | Generates a 'non space' character, i.e. any ascii except
     ' ', '\t', '\n' and '\r'.
-}
nonSpace :: Gen Char
nonSpace :: Gen Char
nonSpace = [Char] -> Gen Char
forall a. (Eq a, Arbitrary a) => [a] -> Gen a
notOneof [Char]
" \t\n\r"

{- | Generates any whitespace character, including new lines.
-}
whitespace :: Gen Char
whitespace :: Gen Char
whitespace = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof [Gen Char
space,Gen Char
newline]

{- | Generates a whitespace charecter, not a newline.
-}
space :: Gen Char
space :: Gen Char
space = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
" \t")

{- | Generates either a '\n' or '\r'.
-}
newline :: Gen Char
newline :: Gen Char
newline = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"\n\r")

letters :: String
letters :: [Char]
letters = [Char]
"abcdefghijklmnopqrstuvwxyz"

{- | Generates any lower case alpha character.
-}
lowerAlpha :: Gen Char
lowerAlpha :: Gen Char
lowerAlpha = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
letters)

{- | Generates any upper case alpha character.
-}
upperAlpha :: Gen Char
upperAlpha :: Gen Char
upperAlpha = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> Gen Char) -> (Char -> Char) -> Char -> Gen Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Char
toUpper) [Char]
letters)

{- | Generates a digit character.
-}
numeric :: Gen Char
numeric :: Gen Char
numeric = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"1234567890")

{- | Generates one or other of '(' and ')'.
-}
parenthesis :: Gen Char
parenthesis :: Gen Char
parenthesis = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"()")

{- | Generates one or other of '[' and ']'.
-}
bracket :: Gen Char
bracket :: Gen Char
bracket = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"[]")

{- | Generates one or other of '{' and '}'.
-}
brace :: Gen Char
brace :: Gen Char
brace = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"{}")

{- | Generates one of '*', '/', '-', '+', '<', '>', '|' and '#'.
-}
operator :: Gen Char
operator :: Gen Char
operator = [Gen Char] -> Gen Char
forall a. [Gen a] -> Gen a
oneof ((Char -> Gen Char) -> [Char] -> [Gen Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Gen Char
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"*/-+<>|#")