使用 QuickCheck 测试一元法则

2024-02-16

是否有用于测试的库或工具laws https://wiki.haskell.org/Monad_laws自定义 monad 的?我目前的黑客尝试是这样的:

  • Define Arbitrary1, 如同Eq1, Show1 etc.
  • 定义一个包装的辅助类型Arbitrary1 as Arbitrary.
  • 定义一元法则的测试(例如)。

这些是否已经在某处实施?


{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
import Data.Functor.Classes
import Data.Proxy
import Test.QuickCheck
import Test.QuickCheck.Function
import Test.QuickCheck.Poly

Define Arbitrary1 for * -> * types:

class Arbitrary1 m where
    arbitrary1 :: (Arbitrary a) => Gen (m a)
    shrink1 :: (Arbitrary a) => m a -> [m a]
    shrink1 _ = []

和一个辅助包装器,以便我们可以使用与Arbitrary:

newtype Action m a = Action { getAction :: m a }

instance (Arbitrary a, Arbitrary1 m) => Arbitrary (Action m a) where
    arbitrary = Action <$> arbitrary1
    shrink = map Action . shrink1 . getAction

instance (Show a, Show1 m) => Show (Action m a) where
    showsPrec p = showsPrec1 p . getAction

现在我们可以编写这样的测试:

-- (m >>= f) >>= g  ≡   m >>= (\x -> f x >>= g)
testBindAssoc :: forall m . (Monad m, Arbitrary1 m, Show1 m, Eq1 m) => Proxy m -> Property
testBindAssoc _ =
    forAllShrink (arbitrary :: Gen (Action m A)) shrink $ \m' ->
    forAllShrink (arbitrary :: Gen (Fun A (Action m B))) shrink $ \f' ->
    forAllShrink (arbitrary :: Gen (Fun B (Action m C))) shrink $ \g' ->
    let m = getAction m'
        f = getAction <$> apply f'
        g = getAction <$> apply g'
        k = (m >>= f) >>= g
        l = m >>= (\x -> f x >>= g)
    in counterexample (showsPrec1 0 k . showString " != " . showsPrec1 0 l $ "")
        $ k `eq1` l

让我们写一个破碎的Writer monad:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.Writer

newtype MyMonad w a = MyMonad { runMyMonad :: Writer w a }
  deriving (Functor, Applicative)

instance (Monoid w) => Monad (MyMonad w) where
    return = pure
    k >>= f = let (a, w) = runWriter . runMyMonad $ k
              in MyMonad $ writer (a, w <> w) >>= (runMyMonad . f)
--                                    ^ broken here

getMyMonad :: MyMonad w a -> (a, w)
getMyMonad = runWriter . runMyMonad

instance (Eq w) => Eq1 (MyMonad w) where
    eq1 k l = getMyMonad k == getMyMonad l

instance (Show w) => Show1 (MyMonad w) where
    showsPrec1 p k = showsPrec p (getMyMonad k)

instance (Monoid w, Arbitrary w) => Arbitrary1 (MyMonad w) where
    arbitrary1 = MyMonad . writer <$> arbitrary
    shrink1 = map (MyMonad . writer) . shrink . getMyMonad

main :: IO ()
main = quickCheck (testBindAssoc (Proxy :: Proxy (MyMonad (Sum Int))))

失败:

*** Failed! Falsifiable (after 2 tests and 13 shrinks):   
(1,Sum {getSum = 1})
{_->(1,Sum {getSum = 0})}
{_->(1,Sum {getSum = 0})}
(1,Sum {getSum = 4}) != (1,Sum {getSum = 2})

有什么改进的想法吗?


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 QuickCheck 测试一元法则 的相关文章

  • 如何测试自定义 StateT 的 Monad 实例?

    我正在学习 Monad Transformers 其中一个练习要求实现 Monad 实例StateT 我想使用以下方法测试我的实现是否符合 Monad 法则validity https github com NorfairKing vali
  • 通过 Java 独立应用程序运行 JMeter 测试用例,无需在本地安装 JMeter。

    我正在尝试使用以下命令执行 JMeter 测试用例 我是否有另一种方法可以在不本地安装 JMeter 的情况下执行测试用例 这里我必须提供 JMeterUtils 的 JMeter HOME 路径 JMeter Engine Standar
  • 使用 NUnit 或 XUnit 时如何将参数传递给 dotnet test 命令

    我正在使用 C 和 NET Core Selenium 和 NUnit 开发一些端到端测试 现在我想写一个登录测试用例 我的测试是从控制台开始的 只需使用dotnet test命令 我只想将用户名和密码传递给此命令并在我的测试中获取它们 我
  • 为什么 GHC 在这里推断出单态类型,即使禁用了单态限制?

    这是由解析 f f pure 的类型 https stackoverflow com questions 55388119 resolving the type of f f pure 55388309 noredirect 1 comme
  • Haskell/Idris 中的开放类型级别证明

    在 Idris Haskell 中 可以通过注释类型并使用 GADT 构造函数 例如使用 Vect 来证明数据的属性 但这需要将属性硬编码到类型中 例如 Vect 必须是与 List 不同的类型 是否有可能拥有具有开放属性集的类型 例如同时
  • 如何从 Visual Studio 以调试模式运行 NUnit?

    我最近正在为我一直在研究的一些 C 构建一个测试框架 我在工作区中设置了 NUnit 和一个新项目来测试该组件 如果我从 Nunit v2 4 加载单元测试 一切都会很好 但我已经到了在调试模式下运行并设置一些断点非常有用的地步 我已经尝试
  • Guice 字段注入不起作用(返回 null)

    我在使用 Guice 时遇到空值问题 接下来我将向您展示一个类似场景的示例 我知道字段注入是一种不好的做法 但我希望它在演示中像这样工作 我有一个名为B 这是我要注入的 class B Inject public B public void
  • Rspec 控制器测试,传递 JSON 参数

    我试图实现以下目标 在 RSpec 控制器测试中创建 POST json 请求 并向其传递参数 这是我的代码 it returns access token do post login email bla password bla1 for
  • Haskell if-then-else 条件中的“解析输入错误”

    当我尝试编译以下 do 块时 它会抛出错误 输入 conn 上的解析错误 我尝试了许多不同的 if then else 语句配置 但均无济于事 在我添加条件之前 数据库逻辑就起作用了 所以这没有问题 else 中是否有太多行 有没有办法在不
  • 当约束成立时,将没有约束的 GADT 转换为另一个有约束的 GADT

    我们能否将构造函数没有给定约束的 GADT 转换为具有上述约束的 GADT 我想这样做是因为我想要深度嵌入箭头并用 目前 似乎需要的表示做一些有趣的事情Typeable 一个理由 https stackoverflow com a 1223
  • Haskell:确定函数数量的函数?

    可以写一个函数吗arity a gt Integer确定任意函数的数量 使得 gt arity map 2 gt arity foldr 3 gt arity id 1 gt arity hello 0 是的 这可以非常非常容易地完成 ar
  • 为什么对本地列表求和比用“GHC -O2”对教会编码列表求和慢?

    为了测试教会编码的列表如何针对用户定义的列表和本机列表执行 我准备了 3 个基准测试 用户定义的列表 data List a Cons a List a Nil deriving Show lenumTil n go n Nil where
  • 所有junit测试后的清理

    在我的项目中 我必须在所有测试之前进行一些存储库设置 这是使用一些棘手的静态规则来完成的 然而 在所有测试之后我不知道如何进行清理 我不想保留一些神奇的静态数字来引用所有测试方法的数量 我应该一直维护它 最受赞赏的方法是添加一些侦听器 该侦
  • 如何在浏览器中模拟纬度和经度值(用于地理位置测试)?

    我正在开发一个网络应用程序 它要求我在浏览器中模拟纬度和经度值以进行地理位置测试 有人有测试基于地理定位的应用程序的经验吗 提前致谢 伪造地理位置 您想要在 Firefox 中伪造您的位置的原因有很多 一个很好的理由是在没有无线局域网卡的计
  • 不理解 Monoid 定义中态射的表示法

    我试图理解什么Monoid是从范畴论的角度来看的 但我对用来描述它的符号有点困惑 这是维基百科 在范畴论中 幺半群范畴 C I 中的幺半群 或幺半群对象 M 是一个对象 M 和两个态射 M M M 称为乘法 I M 称为单位 我的困惑在于态
  • parList 和 parBuffer 如何选择?

    我从 haskell 并行开始 我已经成功学习了如何使用一些策略 例如 r0 rseq rdeepseq parList parMap 现在我正在进一步寻求更高的效率 所以这是我的问题 有什么区别parList and parBuffer
  • 如何获得具有超载字段名称的经典镜头?

    我正在尝试为具有相同字段名称的记录构建镜头 除此之外 我试图 包装 扩展 这些基本记录 并希望相同的字段名称适用于包装 扩展的记录 我相信 优雅的镜头就是这样做的 我如何让以下内容发挥作用 Data types for context of
  • 如何在Haskell中定义一个允许统一访问不同记录的类?

    我有两条记录 它们都有一个我想要提取以显示的字段 我如何安排事物以便可以使用相同的功能来操纵它们 由于它们有不同的字段 在本例中firstName and buildingName 这是它们的名称字段 它们每个都需要一些 适配器 代码来映射
  • 如何测试哈希函数?

    有没有办法测试哈希函数的质量 我希望在哈希表中使用时具有良好的分布 如果这可以在单元测试中验证 那就太好了 EDIT 为了澄清 我的问题是我已经使用了longJava 中的值的方式是第一个 32 位编码一个 ID 第二个 32 位编码另一个
  • 双共体的方法是什么?

    在思考建议哪些更有用的标准课程时到这个 https stackoverflow com a 40833245 745903 class Coordinate c where createCoordinate x gt y gt c x y

随机推荐

  • 如何在 Visual Studio 2019 16.8.3 Build 中的 ASP.NET Core API 3.1 项目上禁用 SSL?

    如果您在创建项目时已经将 SSL 设置为不使用 SSL 那么您将如何禁用 SSL 如果我尝试创建一个不使用 SSL 的新 ASP NET API 3 1 项目 那么当您第一次运行它时它会正常工作 但就我而言 我想使用运行它 Project
  • Odoo - 使用 colspan 或可能是 col 进行视图定制

    我正在使用 odoo 10 e 早些时候我问了一个问题 我们如何合并两个或多个标头以针对多个字段显示一个标头合并 one2many 中的两个字段标题 https stackoverflow com questions 45377060 od
  • 如何在 Visual Studio 代码上删除 git 存储库(laravel 项目)

    我有一个致力于 git 的小型 Laravel 项目 然后我通过手动成功删除了远程存储库 设置 gt 删除此存储库 它工作正常 但是一旦我尝试在 vs code 上创建新的存储库 然后我就得到了 git init Reinitialized
  • 使用 android.accounts 身份验证器时出现问题

    我是 android accounts api 的新手 现在我试图用它们做一些事情 但出现了一个看似虚拟的问题 我已经为我的应用程序创建了一个身份验证器 但尚未实现抽象方法 它的图标成功出现在系统 添加帐户 窗口中 我知道当我单击它时 将调
  • 关于 pthread_cond_signal 和 pthread_cond_wait

    我有以下问题pthread cond 信号 and pthread cond wait 例如 在下面的代码中 根据我的理解 当增量计数 calls pthread cond 信号 计数 125 in 观看次数只能在之后执行计数互斥体已解锁于
  • 二分查找计算平方根 (Java)

    我需要帮助编写一个程序 该程序使用二分搜索递归计算输入非负整数的平方根 向下舍入到最接近的整数 这是我到目前为止所拥有的 import java util Scanner public class Sqrt public static vo
  • xcode 4.2 位置模拟器和时区

    我在运行时注意到 xcode 模拟器中有一个漂亮的设置 我可以更改当前位置 从而模拟基于位置的测试 但是 当我尝试使用 NSDateFormatter 获取日期时 当地日期仍处于太平洋标准时间 我在太平洋时区 NSDateFormatter
  • 如何在 ios 中的联系人表视图中实现搜索栏 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在 viewdidload 中有以下代码 totalstring NSMutableArray alloc initWithObje
  • 比较 R 中的时间

    我有两列 例如 A 和 B 时间格式为 HH MM A B 00 00 06 00 str A 和 str B 给出 字符 我想做一个比较 例如 Comment lt ifelse hour part A lt hour part B De
  • Asp.Net System.Web.Routing 不会路由 URL,除非最后有 .aspx

    我的路由有一个奇怪的问题 我有一个现有网站 我正在尝试将其添加到其中 它有效 但前提是 aspx 位于 URL 末尾 如果我删除 aspx 则会出现错误 找不到资源 我创建了一个快速测试网站并将代码复制到其中 它工作得很好 两者之间的代码是
  • Photoshop 文本工具在文本开头添加标点符号[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在使用 Photoshop 时遇到了一个奇怪的问题 当我使用文字工具时 我可以正常键入字母 但是当我键入任何标点符号时 它会添加到文本的
  • PG::ConnectionBad:致命:用户“用户名”错误的对等身份验证失败

    当我尝试使用 User connection 或 generic table connection 连接到我的 pg 数据库时 出现此错误 PG ConnectionBad 致命 用户 用户名 的对等身份验证失败 我仔细检查了我的datab
  • 我应该如何将 redux 与不会重用的嵌套子组件一起使用?

    我正在开发一个具有许多子组件的组件 其中一些子组件嵌套了五层 我对使用 redux 感兴趣 因为它的优点是在公共状态原子中拥有单一的事实来源 我不明白的是智能 愚蠢组件的推荐 并将提供者置于主要组件之上 并通过道具传递所有内容 如果我这样做
  • gae 样板文档

    在为 App Engine 寻找一个好的社交登录包时 我尝试了 gae boilerplate 但我发现除了自述文件之外没有任何文档 我认为这根本不够 我有很多问题 其中包括 样板文件应该用作库还是根据需要下载并修改 样板应该如何更新 每个
  • Python yaml:ModuleNotFoundError

    我在 conda 中创建了一个新环境并在那里安装了 yaml conda list grep yaml yaml 0 1 7 had09818 2 但我无法导入它 python c import yaml Traceback most re
  • 如何构建微服务前端

    Let s say I have a dozen microservices I am wondering where should the front end go Let s say front end is HTML Javascri
  • 迭代时修改 Java8 流中的对象

    在 Java8 流中 我可以修改 更新其中的对象吗 例如 List
  • 如何纠正错误“从创建它的线程以外的线程访问”?

    下面的代码给了我下面的错误 我想我需要 InvokeRequired 但我不明白我该如何使用 跨线程操作无效 从创建它的线程以外的线程访问控制 listBox1 代码 using System Collections Generic usi
  • Eclipse 中不同的断点图标有何含义?

    在 Eclipse 中使用断点时 我有时会注意到它们有不同的图标 注释 左侧栏上的标记 有时它只是一个蓝色的球 有时上面有一个复选标记 有时它是十字形的 所有这些注释是什么意思 蓝色球 常规断点 活动 可能设置了命中计数 空球 即白色 断点
  • 使用 QuickCheck 测试一元法则

    是否有用于测试的库或工具laws https wiki haskell org Monad laws自定义 monad 的 我目前的黑客尝试是这样的 Define Arbitrary1 如同Eq1 Show1 etc 定义一个包装的辅助类型