尽管在使用跳棋测试幺半群法时定义了一个,但没有任意实例

No instance of Arbitrary despite defining one while using checkers to test Monoid laws

我正在阅读 Haskellbook and trying to test Monoid laws for a Monoid instance for a simple Bool like data type using the checkers 图书馆。但是当我尝试加载 ghci 中的代码时,出现以下错误:

BadMonoid.hs:21:20: error:
    • No instance for (QuickCheck-2.14:Test.QuickCheck.Arbitrary.Arbitrary
                         Bull)
        arising from a use of ‘monoid’
    • In the first argument of ‘quickBatch’, namely ‘(monoid Twoo)’
      In the expression: quickBatch (monoid Twoo)
      In an equation for ‘main’: main = quickBatch (monoid Twoo)
   |
21 | main = quickBatch (monoid Twoo)
   |                    ^^^^^^^^^^^
Failed, no modules loaded.

尽管如此,我已经为我的数据类型 Bull 定义了一个 Arbitrary 实例。在网上和Stack Overflow上搜索了一下,找到了一个相关的。我已经尝试了那里给出的解决方案(使用 GHC.Generics),但它导致了同样的错误。 这是代码:

module BadMonoid where
import Data.Monoid
import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes

data Bull = Fools | Twoo deriving (Eq, Show)

instance Arbitrary Bull where
  arbitrary = frequency [(1, return Fools), (1, return Twoo)]

instance Monoid Bull where
  mempty = Fools

instance Semigroup Bull where
  (<>) _ _ = Fools

instance EqProp Bull where (=-=) = eq

main :: IO ()
main = quickBatch (monoid Twoo)

问题是安装了两个不兼容的 QuickCheck 版本。我们可以从错误消息中看出,因为它在类型中提到了版本(QuickCheck-2.14):

    • No instance for (QuickCheck-2.14:Test.QuickCheck.Arbitrary.Arbitrary
                         Bull)

正如 Daniel 提到的,解决方案是创建一个依赖 QuickCheckcheckers 的 Cabal 项目,并使用 Cabal 命令(例如 cabal repl)而不是直接使用 GHC。


默认情况下,GHC 可以看到机器上安装的每个包的每个版本。但它不知道如何在它们之间进行选择。如果 运行 自己,它将选择它首先找到的任何包版本——它们可能彼此不一致。

进入卡巴尔。 Cabal 的主要功能是它的求解器:它可以 select 一组一致的包,并告诉 GHC 使用这些包。这就是创建 Cabal 项目解决问题的原因。

一般来说,它是 运行 cabal install --lib 的反模式。 (安装可执行文件没问题,因为它们是独立的。)如果您需要从 Hackage 安装库,请创建一个依赖库的 Cabal 项目。