使用QuickCheck为给定功能生成多个任意参数 [英] Using QuickCheck to generate multiple arbitrary parameters for a given function

查看:93
本文介绍了使用QuickCheck为给定功能生成多个任意参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文

我具有以下功能:

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 aBS.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的参数上使用genRSAgenRSAMessage,还是有替代方法?

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

在这里,gGen 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆