使用QuickCheck为给定功能生成多个任意参数 [英] Using QuickCheck to generate multiple arbitrary parameters for a given function
问题描述
上下文
我具有以下功能:
prop_SignAndVerify :: (PrivKey a b) => Blind a -> BS.ByteString -> Bool
prop_SignAndVerify bsk msg = case verify pk msg sig of
Left e -> error e
Right b -> b
where
sk = getBlind bsk
pk = toPublic sk
sig = case sign sk msg of
Left e -> error e
Right s -> s
我想做类似的事情:
-- instance PrivKey RSA.PrivateKey RSA.PublicKey where...
genRSA :: Gen RSA.PrivateKey
genRSAMessage :: Gen BS.ByteString
main = do
quickCheck . verbose
$ forAll genRSA
$ forAll genRSAMessage prop_SignAndVerify
也就是说,我想使用显式生成器在prop_SignAndVerify
的参数中为Blind a
和BS.ByteString
生成任意值.
That is, I would like to use explicit generators to generate arbitrary values for Blind a
and BS.ByteString
in the parameters of prop_SignAndVerify
.
但是,上面的代码不起作用,因为函数forAll
具有类型签名:
The code above, however, doesn't work, because the function forAll
has type signature:
forAll :: (Show a, Testable prop) => Gen a -> (a -> prop) -> Property
此函数运行生成器,并将生成的任意值苹果化为(a -> prop)
,并返回Property
.但是,该Property
不能进一步部分应用.它隐藏了基础功能.
This function runs the generator and apples the generated arbitrary value to (a -> prop)
, returning a Property
. This Property
however cannot be further partially applied; it hides the underlying function.
我认为我们需要上述工作才能实现:
I think what we need for the above to work would be something like:
forAll' :: (Show a, Testable prop) => Gen a -> (a -> prop) -> prop
问题
所以我的问题是,如何在prop_SignAndVerify
的参数上使用genRSA
和genRSAMessage
,还是有替代方法?
So my question is, how can I use genRSA
and genRSAMessage
over the parameters of prop_SignAndVerify
, or is there an alternative approach?
谢谢
推荐答案
您可以利用Gen
的单调性质从属性中组合出更复杂的Gen
值:
You could take advantage of the monadic nature of Gen
to compose a more complex Gen
value from your property:
main =
let g = do
key <- genRSA
message <- genRSAMessage
return $ prop_SignAndVerify (Blind key) message
in quickCheck . verbose $ forAll g id
在这里,g
是Gen Bool
值.
或者,您可以利用Gen
的应用性质,并使用<*>
编写g
:
Alternatively, you can take advantage of the applicative nature of Gen
and compose g
using <*>
:
main =
let g =
return (\key message -> prop_SignAndVerify (Blind key) message)
<*> genRSA
<*> genRSAMessage
in quickCheck . verbose $ forAll g id
在这里
g
仍然是Gen Bool
值.
这篇关于使用QuickCheck为给定功能生成多个任意参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!