简体   繁体   English

如何在main中使用quickcheck

[英]How to use quickcheck in main

I am writing a test for a binary search function I wrote. 我正在编写一个我写的二进制搜索函数的测试。

module Tests where

import Data.List (sort)
import Test.QuickCheck
import BinarySearch (binarySearch)

prop_equals_elem x xs = (binarySearch x $ sort xs) == (x `elem` xs)

args = Args {replay = Nothing, maxSuccess = 200, maxDiscard=200, maxSize=200, chatty = False}

main = do
    quickCheck (prop_equals_elem :: (Ord a) => a -> [a] -> Bool)

It works well using quickCheck in ghci but when I try to run main it gives the error 它在ghci中使用quickCheck很好用,但是当我尝试运行main时它会给出错误

Tests.hs:12:5:
    Ambiguous type variable `a0' in the constraints:
      (Arbitrary a0) arising from a use of `quickCheckWith'
          at Tests.hs:12:5-18
      (Show a0) arising from a use of `quickCheckWith'
          at Tests.hs:12:5-18
      (Ord a0) arising from an expression type signature
          at Tests.hs:12:26-72

Why does this not work in main but does in ghci? 为什么这不是主要的,但在ghci中呢?

This is likely caused by the extended defaulting rules in GHCi . 这可能是由GHCi中延长的违约规则引起的。

When testing a function like this, you need to use a concrete element type. 在测试这样的函数时,需要使用具体的元素类型。 GHCi will default the element type to () because of the extended rules, but this will not happen when compiling the code normally, so GHC is telling you that it cannot figure out which element type to use. 由于扩展规则,GHCi会将元素类型默认为() ,但在正常编译代码时不会发生这种情况,因此GHC告诉您它无法确定要使用的元素类型。

You can for example use Int instead for the test. 例如,您可以使用Int代替测试。 () is pretty useless for testing this function, as all elements would be the same. ()对于测试这个函数是没有用的,因为所有元素都是相同的。

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)

If it works for Int , it should work for any type due to parametricity. 如果它适用于Int ,由于参数化,它应适用于任何类型。

When you run a QuickCheck test, QuickCheck needs to know how to generate data. 运行QuickCheck测试时,QuickCheck需要知道如何生成数据。 Here, you've told it only that your code should work with an arbitrary type of the Ord type class, which isn't enough for it to start testing. 在这里,您只告诉它您的代码应该使用任意类型的Ord类型,这对于它开始测试是不够的。 Hence the error about ambiguous type classes. 因此关于模糊类型类的错误。

If you just need an arbitrary Ord instance, as it appears here, then something like Int would be a good choice for your testing. 如果您只需要一个任意的Ord实例,就像它在这里看到的那样,那么像Int这样的东西将是您测试的不错选择。 It's a simple type with a linear order. 这是一个带线性顺序的简单类型。 So try fixing your type to Int in main , as in: 因此,尝试在main中将您的类型修复为Int ,如:

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)

As for why it works in GHCi, the answer is defaulting. 至于它为什么在GHCi中工作,答案是默认的。 GHCi defaults type variables to () whenever possible, just to avoid giving spurious errors in situations where you really don't care about a value. GHCi尽可能将类型变量默认为() ,以避免在您真正不关心值的情况下给出虚假错误。 Actually that's an awful choice: you won't test anything interesting by only testing with the () type! 实际上这是一个糟糕的选择:你不会只用()类型测试来测试任何有趣的东西! So again, the explicit type signature is better. 再次,显式类型签名更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM