没有因使用“prop”而产生的(Arbitrary Natural)实例

No instance for (Arbitrary Natural) arising from a use of ‘prop’

我正在尝试为二进有理数的实现编写以下测试。

import Numeric.Natural

import Test.Hspec
import Test.Hspec.QuickCheck

import Dyadics

dyadic_add :: Integer -> Natural -> Integer -> Natural -> Bool
dyadic_add n1 p1 n2 p2 = 
    dyadic_to_rational (d1 `plus` d2) == (dyadic_to_rational d1) + (dyadic_to_rational d2) where
        d1 = Dyadic n1 p1
        d2 = Dyadic n2 p2

main :: IO ()
main = hspec $ do
    describe "Dyadic properties" $ do
        prop "dyadics add like rationals" $ dyadic_add

我是 haskell 的新手,所以我几乎不明白我在做什么。

我首先用这个签名写了测试; dyadic_add :: Dyadic -> Dyadic -> Bool。 鉴于我的数据类型只是 data Dyadic = Dyadic Integer Natural,我假设生成随机 Dyadics 是 QuickCheck 可以弄清楚如何做的事情,但显然不是——我收到错误 No instance for Test.QuickCheck.Arbitrary.Arbitrary Dyadic arising from a use of ‘prop’.

我发现这意味着我需要将 Dyadics 实现为 Arbitrary 的一个实例(就像 ShowEq 的实例一样)。我也许想出了如何做到这一点,但它看起来很乱而且不太管用,然后我意识到我可以重写测试以接受 Integers 和 Naturals。

但是,我收到了 Natural 相同的错误消息; No instance for (QuickCheck-2.14.2:Test.QuickCheck.Arbitrary.Arbitrary Natural) arising from a use of ‘prop’。 这让我非常惊讶——QuickCheck 真的不知道如何生成任意 Natural 吗?我想我也许可以弄清楚如何做到这一点,但我感觉 QuickCheck 中有很多预先存在的功能,我可能应该使用它们,而且我 运行 反对我的尝试阅读 QuickCheck 示例代码时解析 Haskell 的能力。 best/simplest/most haskell 惯用的方法是什么?

quickcheck-instances 中实现了这些类型中的一堆。只需将其添加到您的依赖项中,import Test.QuickCheck.Instances.Natural,您就可以开始了!