haskell - 尽管在使用检查器测试 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)
解决方案
问题是安装了两个不兼容的 QuickCheck 版本。我们可以从错误消息中看出,因为它QuickCheck-2.14
在类型中提到了版本 ( ):
• No instance for (QuickCheck-2.14:Test.QuickCheck.Arbitrary.Arbitrary
Bull)
正如 Daniel 所提到的,解决方案是创建一个依赖于QuickCheck
and的 Cabal 项目checkers
,并直接使用 Cabal 命令(例如cabal repl
)而不是 GHC。
默认情况下,GHC 可以查看机器上安装的每个软件包的每个版本。但它不知道如何在它们之间进行选择。如果单独运行,它将选择它首先找到的任何包版本——这可能彼此不一致。
进入阴谋集团。Cabal 的主要特点是它的求解器:它可以选择一组一致的包,并告诉 GHC只使用这些包。这就是为什么创建一个 Cabal 项目可以解决这个问题。
一般来说,运行是一种反模式cabal install --lib
。(安装可执行文件是可以的,因为它们是独立的。)如果您需要从 Hackage 安装库,请创建一个依赖于库的 Cabal 项目。
推荐阅读
- node.js - 在循环中插入多个文档会创建多个相同的文档
- javascript - Reactjs,当我删除元素时数组索引发生变化
- android - 如何在 Gradle 脚本中根据环境变量动态编辑 Android Manifest 文件
- html - 如何使用 CSS 删除输入文本值选择突出显示?
- ios - iOS:iOS13显示popover边框的问题
- javascript - GET api 在 chrome 上运行良好,但在 IE11 上却不行
- c++ - TinyXML 和标签和格式问题
- c# - 为什么此应用程序要查找引用程序集的旧版本、已删除版本?
- web-component - Lit-element:如何使用非 esm npm 包?
- python - 按外键计数和排序,但使用另一列