跳棋和 EqProp
Checkers and EqProp
我正在浏览 Haskell Book and the chapter on applicatives started using the checkers 库进行测试。
这个库引入了EqProp
类型类,我不明白它和Eq
有什么不同。大多数需要 EqProp
的示例在后台都使用 Eq
。
为什么人们使用跳棋而不是 QuickCheck?
重点是函数和无限值不具有可判定相等性(Eq
),但可以测试为此(EqProp
)通过观察(随机)有限片段。
This library introduces the EqProp
typeclass, and I don't understand how this differs from Eq
.
(==)
来自 Eq
给你一个 Bool
; EqProp
中的 (=-=)
为您提供快速检查 Property
。如果您有 Eq
的实例,您也可以将其设为 EqProp
实例,as witnessed by eq
. The interesting instances of EqProp
are those that aren't instances of Eq
, such as functions (cf. ).
Why do people use checkers over Quickcheck?
Checkers 是一套基于 QuickCheck 的额外工具。因为它的 readme and Hackage description suggest, one of its goals is making it easy to express class laws as Quickcheck properties. For instance, note how the definition of the applicative
"test batch",我将在下面引用,看起来很像我们经常写的 Applicative
法则,并且很好 self-documenting.
(请随意跳过 top-level 签名中的簿记约束。另请注意,m (a,b,c)
参数以 simplest-thing-that-could-possibly-work 的方式仅用于类型特化,意图是您通过 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)
我正在浏览 Haskell Book and the chapter on applicatives started using the checkers 库进行测试。
这个库引入了EqProp
类型类,我不明白它和Eq
有什么不同。大多数需要 EqProp
的示例在后台都使用 Eq
。
为什么人们使用跳棋而不是 QuickCheck?
重点是函数和无限值不具有可判定相等性(Eq
),但可以测试为此(EqProp
)通过观察(随机)有限片段。
This library introduces the
EqProp
typeclass, and I don't understand how this differs fromEq
.
(==)
来自 Eq
给你一个 Bool
; EqProp
中的 (=-=)
为您提供快速检查 Property
。如果您有 Eq
的实例,您也可以将其设为 EqProp
实例,as witnessed by eq
. The interesting instances of EqProp
are those that aren't instances of Eq
, such as functions (cf.
Why do people use checkers over Quickcheck?
Checkers 是一套基于 QuickCheck 的额外工具。因为它的 readme and Hackage description suggest, one of its goals is making it easy to express class laws as Quickcheck properties. For instance, note how the definition of the applicative
"test batch",我将在下面引用,看起来很像我们经常写的 Applicative
法则,并且很好 self-documenting.
(请随意跳过 top-level 签名中的簿记约束。另请注意,m (a,b,c)
参数以 simplest-thing-that-could-possibly-work 的方式仅用于类型特化,意图是您通过 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)