tl;dr
I'd like to understand how to use Test.QuickCheck
to test functions whose arguments are passed to smart constructors and/or assumed as coming out of a smart constructor.
Long version
In a module I have a user defined type like this:
newtype SpecialStr = SpecialStr { getStr :: String }
As the name implies, SpecialStr
is quite special, in that the wrapped String
is not "any" string, but it has to satisfy some properties. To enforce this, I don't export the value constructor from the module, but a smart constructor:
specialStr :: String -> SpecialStr
specialStr str = assert (isValid str) $ SpecialStr str
where
isValid :: String -> Bool
isValid = and . map (`elem` "abcdef") -- this is just an example logic
Naturally, I've defined some functions that operate with these SpecialStr
s, such as
someFunc :: String -> [SpecialStr]
someFunc str = -- uses smart constructor
someOtherFunc :: (Int, SpecialStr) -> Whatever
someOtherFunc = -- assumes the input has been created via the smart constructor, i.e. assumes it's valid
where maybe someFunc
is fed with a String
, and then the outcoming [SpecialStr]
is zipped with [1..]
and the result is fed to someOtherFunc
, just to make a random example.
Now my question is: how do I test these functions using QuickCheck
?