我正在浏览Haskell Book,有关应用程序的章节开始使用checkers库进行测试。

这个库介绍了EqProp类型类,我不明白它与Eq有何不同。无论如何,大多数要求EqProp的示例都在后台使用Eq

人们为什么在QuickCheck上使用检查器?

最佳答案

这个库介绍了EqProp类型类,我不明白这与Eq有何不同。
(==)中的Eq给您一个Bool; (=-=)中的EqProp为您提供QuickCheck Property。如果您有Eq实例,则还可以使其成为EqProp实例as witnessed by eq 。有趣的EqProp实例是那些不是Eq实例的实例,例如函数(参见Li-yao Xia's answer)。

人们为什么在Quickcheck上使用检查器?

Checkers是基于QuickCheck构建的一组额外工具。正如其readmeHackage description所暗示的那样,其目标之一是使其易于将类定律表达为Quickcheck属性。例如,请注意下面将引用的the applicative "test batch"的定义与我们经常编写Applicative法则的方式非常相似,并且很好地自我记录。

(随意跳过顶级签名中的簿记约束。还要注意,m (a,b,c)参数以一种最简单的,可能的工作方式,仅用于类型专门化,目的是您通过例如undefined :: [(Int,Int,Int)]以测试Applicative的列表实例。)

-- | Properties to check that the 'Applicative' @m@ satisfies the applicative
-- properties
applicative :: forall m a b c.
               ( Applicative m
               , Arbitrary a, CoArbitrary a, Arbitrary b, Arbitrary (m a)
               , Arbitrary (m (b -> c)), Show (m (b -> c))
               , Arbitrary (m (a -> b)), Show (m (a -> b))
               , Show a, Show (m a)
               , EqProp (m a), EqProp (m b), EqProp (m c)
               ) =>
               m (a,b,c) -> TestBatch
applicative = const ( "applicative"
                    , [ ("identity"    , property identityP)
                      , ("composition" , property compositionP)
                      , ("homomorphism", property homomorphismP)
                      , ("interchange" , property interchangeP)
                      , ("functor"     , property functorP)
                      ]
                    )
 where
   identityP     :: m a -> Property
   compositionP  :: m (b -> c) -> m (a -> b) -> m a -> Property
   homomorphismP :: (a -> b) -> a -> Property
   interchangeP  :: m (a -> b) -> a -> Property
   functorP      :: (a -> b) -> m a -> Property

   identityP v        = (pure id <*> v) =-= v
   compositionP u v w = (pure (.) <*> u <*> v <*> w) =-= (u <*> (v <*> w))
   homomorphismP f x  = (pure f <*> pure x) =-= (pure (f x) :: m b)
   interchangeP u y   = (u <*> pure y) =-= (pure ($ y) <*> u)
   functorP f x       = (fmap f x) =-= (pure f <*> x)

07-28 13:07