我正在阅读Haskellbook,并尝试使用Bool
库针对简单的checkers数据类型测试Monoid实例的Monoid律。但是,当我尝试在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
实例。我在Internet和Stack Overflow上进行了搜索,发现了一个相关的post。我已经尝试过给定的解决方案(使用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)
[正如丹尼尔提到的,解决方案是创建一个依赖于QuickCheck
和checkers
的Cabal项目,并直接使用Cabal命令(例如cabal repl
)而不是GHC。
默认情况下,GHC可以查看计算机上安装的每个软件包的每个版本。但是它不知道如何在它们之间进行选择。如果单独运行,它将选择首先找到的任何软件包版本-可能彼此不一致。
输入阴谋集团。 Cabal的主要功能是它的求解器:它可以选择一组一致的程序包,并告诉GHC only使用这些程序包。这就是为什么创建Cabal项目可解决此问题的原因。
[通常,它是运行cabal install --lib
的反模式。 (可以安装可执行文件,因为它们是独立的。)如果您需要从Hackage安装库,请创建一个依赖该库的Cabal项目。