首页 > 解决方案 > 尽管在使用检查器测试 Monoid 定律时定义了任意实例,但没有任意实例

问题描述

我正在阅读Haskellbook并尝试使用checkers库测试 Monoid 实例的 Monoid 定律,以获得简单的Bool类似数据类型。但是当我尝试加载代码时,出现以下错误: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.

不过,我已经Arbitrary为我的数据类型定义了一个实例Bull。我在网上和 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)

标签: haskellquickcheckmonoids

解决方案


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

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

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


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

进入阴谋集团。Cabal 的主要特点是它的求解器:它可以选择一组一致的包,并告诉 GHC使用这些包。这就是为什么创建一个 Cabal 项目可以解决这个问题。

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


推荐阅读