Haskell quickcheck - 如何仅生成可打印的字符串 [英] Haskell quickcheck - how to generate only printable strings

查看:106
本文介绍了Haskell quickcheck - 如何仅生成可打印的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组简单的演示程序,它们对字符串进行编码/解码,并且希望为它们生成一些quickCheck测试,但只将测试限制为可打印的字符串。使用守护进程太慢,并且因为生成和拒绝的测试用例过多而失败,所以我想为该域创建一个安全的生成器。



对此的引用我曾经见过要么(1)为 Char 定义自己的 Arbitrary 实例,并使用它为字符串生成仅可打印字符,要么(2)必须包装在 newtype 中自行运行,并为此写入一个任意实例。



但试图做(1)因为在Test.QuickCheck中现在有一个定义,所以如何做到这一点 - 为新类型创建一个 safeChar 生成器,然后又必须为测试函数生成一个适配器? (RWH书籍部分注意到它在推荐这个DIY字符定义时已经过时)。

试图做(2)似乎我可以只是添加对本地化和简单(但失败)的测试命题的守护,或者编写一个新的包装和相关的生成器,这似乎更加混乱。显然这很简单(! )和所有的工具都提供了,但有人可能会建议这是否是一个正确的分析,并举例说明如何做到这一点最好?

解决方案 div>

起点肯定是 genSafeChar 生成器,它可以有 Gen Gen 类型。例如:

  genSafeChar :: Gen Char 
genSafeChar = elements ['a'..'z']

然后,您可以将其构建到 genSafeString 发电机,例如使用 listOf

  genSafeString :: Gen字符串
genSafeString = listOf genSafeChar

此时您有几个合理的选择。为字符串制作一个 newtype 封装器:

  newtype SafeString = SafeString {unwrapSafeString :: String} 
派生显示

实例任意SafeString其中
任意= SafeString< $> genSafeString

(在这种情况下,您可能只需内联定义 genSafeString < code $)

然后你就可以像这样使用它:

  testWibble(SafeString str)= str == str 

或者,您可以使用< a href =http://hackage.haskell.org/package/QuickCheck-2.4.0.1/docs/Test-QuickCheck.html#v%3aforAll> forAll 在每个点你需要一个安全的字符串:

pre $ testWibble = forAll genSafeString $ \str - > str == str


I have a set of simple demo programs which encode/decode strings, and want to generate some quickCheck tests for them, but to limit the tests to printable strings only. Using a guard is too slow and fails because of too many generated and rejected test cases, so I want to create a safe generator for this domain.

The references to this that I have seen say to either (1) define one's own Arbitrary instance for Char and use that to generate only printable characters for strings, or (2) to have to wrapper the functions themselves in a newtype and write an Arbitrary instance for that.

But trying to do (1) it fails because there is now a definition for this in Test.QuickCheck, and so how would one do this - create a safeChar generator for a new type and then again have to produce an adapter to the tested functions? (The RWH book section on this notes that it is out of date in recommending this DIY Char definition.)

Trying to do (2) seems like I can either just add a guard to the test proposition which is localized and simple (but fails), or writing a new wrapper and associated generator, which seems messier.

Clearly this is simple(!) and all the tools are provided, but could someone advise if this is a correct analysis, and give an example of how to best do this?

解决方案

The starting point is definitely a genSafeChar generator, which can have type Gen Char. For example:

genSafeChar :: Gen Char
genSafeChar = elements ['a'..'z']

Then you can build that up into a genSafeString generator, e.g. with listOf:

genSafeString :: Gen String
genSafeString = listOf genSafeChar

At this point you have a couple of reasonable choices. Either make a newtype wrapper for String:

newtype SafeString = SafeString { unwrapSafeString :: String }
    deriving Show

instance Arbitrary SafeString where
    arbitrary = SafeString <$> genSafeString

(in this case you might just inline the definition of genSafeString)

and you can then use it something like this:

testWibble (SafeString str) = str == str

Or, you can use forAll at each point you need a safe string:

testWibble = forAll genSafeString $ \str -> str == str

这篇关于Haskell quickcheck - 如何仅生成可打印的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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