在Haskell书中关于Monoids的一章中,我正在编写quickcheck测试
semigroupAssoc :: (Eq m, S.Semigroup m) => m -> m -> m -> Bool
semigroupAssoc a b c =
(a S.<> (b S.<> c)) == ((a S.<> b) S.<> c)
type IdentAssoc = Identity String -> Identity String -> Identity String -> Bool,调用
quickCheck (semigroupAssoc :: IdentAssoc)以下是任意类型的实例
instance (Arbitrary a) => Arbitrary (Identity a) where
arbitrary = do
a <- Test.QuickCheck.arbitrary
return (Identity a)我的问题是,在我的任意实例中,我可以返回(标识a)或只是a (标识a)是正确的,但只是一个没有编译器错误,并导致无限循环时运行。为什么会这样呢?
发布于 2017-11-14 18:04:58
类型推断将arbitrary调用更改为指向我们现在定义的同一个实例,从而导致无限循环。
instance (Arbitrary a) => Arbitrary (Identity a) where
arbitrary = do
x <- Test.QuickCheck.arbitrary -- this calls arbitrary @ a
return (Identity x)
instance (Arbitrary a) => Arbitrary (Identity a) where
arbitrary = do
x <- Test.QuickCheck.arbitrary -- this calls arbitrary @ (Identity a)
return x每次调用类方法时,编译器都会推断要调用哪个实例。
在前一种情况下,编译器推断x :: a (只有这种类型使代码类型检查!),因此它调用arbitrary @ a。
在后一种情况下,编译器推断x :: Identity a (只有这种类型使代码类型检查!),因此它调用arbitrary @ (Identity a),从而导致无限循环。
https://stackoverflow.com/questions/47292267
复制相似问题