haskell - 我在哪里定义任意实例?
问题描述
我不知道在哪里Arbitrary
为我的数据类型定义实例。如果我把它放在包中,那么包不必要地必须QuickCheck
作为依赖项。如果我把它放在测试中,那么其他包就不能使用这个实例。如果我把它放在一个单独的 test-utils 包中,那么测试也必须放在一个单独的包中,所以它是一个孤儿实例,也 stack test --coverage
不起作用。
还有哪些其他选择?
解决方案
我通常会选择单独的包选项——但后来我不使用stack test --coverage
. 感谢您向我介绍它!
(编辑:我可能会这样做,然后仅将测试标志选项用于运行stack test --coverage --flag thepackage:arbitrary
,这样其他人就不必处理这些标志了。)
--coverage
在问题跟踪器上提出问题也可能是值得的stack
,因为在这种情况下覆盖检查工作会很好。
您要求其他选项 - 最好的选项可能是测试标志。
测试标志
可以在您的 cabal 文件中定义一个标志(默认为 false),如果选择了该标志,它将仅使用您的 QuickCheck 依赖项构建模块。
将所需的代码放在目录中arbitrary
(例如)。然后将以下等效项添加到package.yaml
(第一个片段)或the-library.cabal
(第二个片段)文件的相关部分:
flags:
arbitrary:
description: Compile with arbitrary instances
default: false
manual: true
library:
⁝
when:
- condition: flag(arbitrary)
dependencies:
- QuickCheck
source-dirs:
- arbitrary
flag arbitrary
description: Compile with arbitrary instances
manual: True
default: False
library
⁝
if flag(arbitrary)
hs-source-dirs:
arbitrary
build-depends:
QuickCheck
然后,想要使用实例的包应在其stack.yaml
(1st)或cabal.project
(2nd)文件中添加以下内容:
flag:
the-library:
arbitrary: true
constraints: the-library +arbitrary
但是有一个小问题......目前该库无法仅依赖+arbitrary
其测试套件中的版本,除非它还定义了这样的标志。这可能是一个值得付出的代价。
注意:我还没有测试过下游包装。
Ivan Milenovic 的博客作为初始资源很有用。
DerivingVia/通用实例
可能还有另一种可能性,现在 GHC 8.6 已经发布,带有DerivingVia
. 例如,在Blöndal、Löh 和 Scott (2018)中有一个案例研究Arbitrary
。
您将创建新类型包装器,并Arbitrary
为这些新类型实现。
它并没有完全避免这个问题,因为它是。但是您可能能够以Generic
这样的方式实现这些新类型,即使用可派生的实例generic-arbitrary
与您想要的匹配。
可能还有其他一些选择。特别是,QuickCheck
的依赖关系实际上并没有那么重。还有其他测试库。另外,请注意,已经讨论了将Arbitrary
-like 类型类分离为独立库的讨论。
我也会建议内部库,但这不允许其他包使用您的实例。
推荐阅读
- php - 加载外部 xml 链接返回 false
- r - 在 R 中创建堆积柱形图
- python - 在特定行将列表插入 df 会发出警告
- java - 如何删除字符串中的引号?
- vaadin - 表单关闭后,Vaadin Select 下拉值继续显示?
- flutter - 尝试使用选项卡栏切换数据,但只有第一个选项卡正在工作并且在第二个选项卡上得到空响应
- typescript - 在 Angular 项目中切换分支时节点模块会丢失
- python - 测试时使用 DjangoRestAPIKey
- javascript - JWT Token 不以 Bearer String 开头,并且在发送时以 Bearer 开头的公理
- flutter - 页面打开时开始计数的简单计时器 [Flutter]