如何使用 QuickCheck 为 StateT 编写测试

2023-12-07

StateT 处于Control.Monad.Trans.State.Lazy

里面的函数和m变得更善良使得事情变得困难

{-# LANGUAGE FlexibleContexts #-}
import Test.QuickCheck

newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
instance (CoArbitrary s, Arbitrary s, Arbitrary a) => 
    Arbitrary (StateT s (Maybe) a) where -- doesn't quite work
    arbitrary = undefined

我想这样做的原因是因为我想使用 QuickCheck 检查我编写的 StateT 应用实例(用于练习)是否正确

编辑: 好的,这是我要测试的实例(据说是不正确的)

instance (Monad m) => Applicative (StateT s m) where
    pure x = StateT (\s -> (\a -> (a, s)) <$> pure x)
    StateT smfs <*> StateT smas = StateT $ \s -> liftA2 (\ (f, s) (a, _) -> (f a, s)) (smfs s) (smas s)

你的问题真的很有趣。事实上,使用以下方法验证函子/应用/单子定律会非常好QuickCheck for StateT单子变压器。因为这是最有用的应用之一QuickCheck.

但写作Arbitrary实例为StateT这并非小事。这是可能的。但实际上并没有什么利润可言。你应该使用CoArbitrary以某种聪明的方式输入类。还有耦合扩展。这个想法描述于这篇博文。拥有CoArbitrary实例为a -> b你可以轻松创建Arbitrary实例为StateT.

instance ( CoArbitrary s
         , Arbitrary s
         , Arbitrary a
         , Arbitrary (m a)
         , Monad m
         ) => Arbitrary (StateT s m a)
  where
    arbitrary = StateT <$> promote (\s -> fmap (,s) <$> arbitrary)

然后你可以生成状态:

ghci> (`runStateT` 3) <$> generate (arbitrary @(StateT Int Maybe Bool))
Just (True,3)

你甚至可以写属性:

propStateFunctorId :: forall m s a .
                      ( Arbitrary s
                      , Eq (m (a, s))
                      , Show s
                      , Show (m (a, s))
                      , Functor m
                      )
                   => StateT s m a -> Property
propStateFunctorId st = forAll arbitrary $ \s -> 
                            runStateT (fmap id st) s === runStateT st s

但你不能运行这个属性,因为它需要instance Show for StateT而且你不能为它编写合理的实例:(这就是如何QuickCheck作品。它应该打印失败的反例。如果您不知道哪一项测试失败了,那么了解 100 项测试已通过而 1 项测试失败这一事实并不能真正帮助您。这不是编程竞赛:)

ghci> quickCheck (propStateFunctorId @Maybe @Int @Bool) 
<interactive>:68:1: error:
    • No instance for (Show (StateT Int Maybe Bool))
        arising from a use of ‘quickCheck’

所以不要生成任意的StateT最好生成s and a然后检查属性。

prop_StateTFunctorId :: forall s a .
                      ( Arbitrary s
                      , Arbitrary a
                      , Eq a
                      , Eq s
                      )
                     => s -> a -> Bool
prop_StateTFunctorId s a = let st = pure a
                           in runStateT @_ @Maybe (fmap id st) s == runStateT st s

ghci> quickCheck (prop_StateTFunctorId @Int @Bool) 
+++ OK, passed 100 tests.

这种方法不需要一些高级技能的知识。

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

如何使用 QuickCheck 为 StateT 编写测试 的相关文章

  • 一个目录中的多个 Haskell cabal-packages

    在一个目录中包含多个 cabal 软件包的推荐方法是什么 Why 我有一个包含许多可分离模块的旧项目 由于最初它们只形成一个程序 因此将它们放在同一目录中以便于编译非常方便 而且现在仍然如此 Options 只是忍受并将所有内容 包括保存内
  • Haskell 中的参数数量和无点 [重复]

    这个问题在这里已经有答案了 对于多重模式匹配 不同数量的参数是不可能的 即使是无点的 foo True b b 2 foo id 例如 不起作用 但 foo True 2 foo id 做 有时我们只能在函数的一部分使用 point fre
  • 在帖子上生成最近帖子列表时,如何避免依赖循环?

    所以这有效 create archive html do route idRoute compile do posts lt myRecentFirst gitTimes lt lt loadAll posts let archiveCtx
  • 模式匹配中的 Monoid mempty

    我尝试写一个通用的maximum功能类似于Prelude 我的第一个天真的方法如下所示 maximum F Foldable a Ord b gt a b gt Maybe b maximum mempty Nothing maximum
  • 为什么Haskell没有split函数? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在许多语言中 都有一个函数可以使用指定的分隔符将字符串分成几部分 它经常被称为split 您可以在 Python C Java JavaScri
  • 仪器化状态单子

    我正在努力给予Monad and MonadState的实例State 计算的数量 gt gt return get and put运营 data Counts Counts binds Int returns Int gets Int p
  • 我是否应该使用 GHC Haskell 扩展?

    当我学习 Haskell 时 我发现有很多语言扩展 http haskell org ghc docs latest html users guide ghc language features html在现实生活中使用的代码 作为初学者
  • Control.Arrow 与 Data.Tuple.Extra

    我经常使用以下功能Data Tuple Extra图书馆 first second and both 有等效的 函数Control Arrow 其实我更喜欢Data Tuple Extra因为我完全迷失了文档Control Arrow 使用
  • 在 Haskell 中对单位的组成(例如英寸、美元等)进行建模

    跟进自我之前的一个问题 https stackoverflow com q 73375273 222529 我问如何创建一个可以对单元进行建模的类型 例如Inch 作为 Haskell 中的一种类型 我现在面临的问题是如何对该单元和其他单元
  • 在 Haskell 中为自定义数据类型创建 Read 类型类的实例

    我有一个自定义数据类型Foo Foo a Int b Int 我正在尝试使 Foo 成为 read 的自定义实例 我已经有一个功能了bar String gt Foo我尝试这样做 instance Read Foo a b where re
  • 为什么 GeneralizedNewtypeDeriving 没有安全的 Haskell?

    来自 GHC 手册 第安全语言 http www haskell org ghc docs 7 6 2 html users guide safe haskell html safe language 模块边界控制 使用安全语言编译的 Ha
  • 如何将可选标志解析为 Maybe 值?

    我正在尝试使用optparse 应用程序 https hackage haskell org package optparse applicative 0 11 0 2解析一个Maybe String但我找不到任何地方如何处理Maybe 我
  • 如何在 Haskell 中枚举递归数据类型?

    这篇博文 http lukepalmer wordpress com 2008 05 02 enumerating a context free language 对于如何使用 Omega monad 对角枚举任意语法有一个有趣的解释 他提
  • 'lens' 的阴谋集团依赖性解析失败

    我刚刚做了一个阴谋更新并尝试从 hackage 安装 lens 这给了我以下错误 cabal install j lens Resolving dependencies Configuring dlist 0 7 0 1
  • 谁能解释一下 GHC 对 IO 的定义吗?

    标题非常自我描述 但有一个部分引起了我的注意 newtype IO a IO State RealWorld gt State RealWorld a 剥离newtype 我们得到 State RealWorld gt State Real
  • 为什么haskell中的递归列表这么慢?

    我对 Haskell 很陌生 我在 Haskell 中定义了一个函数 febs Integral a gt a gt a febs n n lt 0 0 n 1 1 n 2 1 otherwise febs n 1 febs n 2 但是
  • GHC 是否使用存在类型的动态调度?

    下面的代码是否使用了 C 或 Java 中所理解的动态调度 据我了解 在最后一行 编译器不可能在编译时知道要调用哪个 实现 但代码会编译并产生正确的结果 有人可以解释一下 这背后有什么样的实现 例如 vptr 吗 LANGUAGE Exis
  • 对元组列表进行排序的函数 - Haskell

    抱歉 这个简单的问题只是我对 haskell 非常陌生 我正在尝试编写一个函数 order 它将对另一个函数 Frequency 生成的元组列表进行排序 频率计算列表中不同元素的数量 a给出一个这样的结果 比如 gt 频率 aabbbccc
  • 在 Haskell 命令行应用程序中提示输入密码

    以下 Haskell 程序提示用户在终端中输入密码 如果输入正确则继续 main do putStrLn Password password lt getLine case hash password member database of
  • Haskell 中的类型化抽象语法和 DSL 设计

    我正在 Haskell 中设计 DSL 我想要进行赋值操作 像这样的东西 下面的代码只是为了在有限的上下文中解释我的问题 我没有类型检查 Stmt 类型 data Stmt forall a Assign String Exp a Assi

随机推荐

  • 在 C# 中对 IList 进行排序

    所以今天我遇到了一个有趣的问题 我们有一个返回 IList 的 WCF Web 服务 直到我想对它进行排序之前 这并不是什么大不了的事 事实证明 IList 接口没有内置排序方法 我最终使用了ArrayList Adapter list S
  • Laravel 棘轮套接字身份验证

    我开始学习 Ratchet reactPHP 我正在使用 laravel 但我谈到了有关安全的问题 如何根据用户是否登录来拒绝 websocket 连接 public function onOpen ConnectionInterface
  • Jersey 2.x 中的过多警告消息

    我不断从任何使用 APPLICATION FORM URLENCODED 表单数据的 POST 操作中收到这些警告消息 A servlet request to the URI local request URI contains form
  • Cordova 相机 - Ionic

    我已经寻找解决方案近两天了 我正在尝试使用 ngCordova 相机插件 我将 ionic yeoman 框架与 AngularJS 结合使用 我所做的是 bower install save ngCordova Added ngCordo
  • SQL Server 插入触发器以及如何引用插入的数据

    高级我有两个表需要镜像一些数据 我无法遍历并更改所有代码以写入这两个表 因此我认为只要将数据插入第一个表 我就可以使用 SQL 触发器将数据插入到第二个表中 这是我被困住的地方 CREATE TRIGGER new trigger INSE
  • 为什么我的 Debug.Write 损坏了?

    有人可以解释为什么我的 Debug Write 无明显原因停止工作 没有输出可见 我在 Windows XP Windows 2003 Server 和 Windows 7 上的 Visual Studio 2008 从未在 2005 上
  • 媒体查询不适用于 iPhone 和 iPad

    media在以下情况下查询不起作用iPhone 5 和 iPad 4 操作系统 我用过以下CSS用于针对不同屏幕设计每个操作系统和设备 我明确检查了我的 iPad 和 iPhone 的宽度和高度 并基于此只有我保留了媒体查询 这有效fine
  • 在 Google 风格的 Python 文档字符串中“写入”?

    在 Google 风格的 Python 文档字符串中 可以指定Args Returns Raises如下 This is an example of Google style Args param1 This is the first pa
  • Magento - 数据库修复工具 - 添加丢失外键问题

    我最近按照此链接运行了数据库修复工具 http www magentocommerce com wiki 1 installation and configuration db repair tool 在说明的底部 它说 添加了缺少的外键或
  • 无法在 .NET 4.5 MVC 应用程序上实现 JSNLog

    Issue 我正在尝试在 MVC 应用程序中使用 JSNLog 目标框架 NET 4 5 我正进入 状态 当前上下文中不存在 JSN 日志 error 我尝试安装JSNLog 2 28 0 但它显示 无法安装包 JSNLog 2 28 0
  • 为什么 Microsoft Visual C# 2008 Express Edition 调试器会随机退出?

    我正在 Microsoft Visual C 2008 Express Edition 中编写多线程 Windows 应用程序 最近 调试器表现得很奇怪 当我使用 F10 单步执行代码行时 有时它会像继续命令 F5 一样解释我的单步执行 F
  • 二维数组邻接算法

    我有一个像这样的二维数组 0 1 0 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 如果我们提取所有 1 的坐标 我们会得到 height width 1 2 1 5 2 1 所以现在我想找到由相邻
  • const 方法使用引用修改对象

    下面的代码调用了一个const方法将引用传递给成员 然后对其进行修改 include
  • 断言 HTTP 状态代码为 200 而不是 500 失败

    我正在尝试对某个请求的 HTTP 状态代码进行功能测试200 not 500 我正在使用 Symfony2 代码如下 public function testIndex client static createClient crawler
  • Xamarin 形成 4 shell 导航,参数复杂

    我正在将带有 Prism 的 xamarin forms 3 x 应用程序迁移到带有 shell 导航的 Forms 4 我是否必须创建自定义解决方案才能将复杂参数传递到新页面 或者 Xamarin 有一些内置功能可以接收字符串参数以外的参
  • 在 AD 服务器上使用 winldap.h 进行 LDAP 搜索

    我正在尝试进行 LDAP 搜索 但它在我的 Active Directory 测试服务器上不起作用 我使用这段代码 include
  • DataTable.Load() 抛出错误:表达式中未定义函数“CountWeekDays”

    我正在使用 Access 数据库并尝试加载 DataTable 对象 但收到了错误 我的查询在标准访问模块中调用名为 CountWeekDays 的公共函数 当通过 Access 本身运行时 会返回正确的结果 为什么在通过 NET 应用程序
  • 为什么这个 JavaScript 调用不会破坏“同源策略”

    我正在使用 jQuery 显示外部 JavaScript 文件 同源策略 没有被破坏的原因是因为它不是 AJAX 请求吗 http jsfiddle net m7q3H 52 小提琴代码 HTML 这里绝对没问题哦 您可以从任何您想要的地方
  • 如何在 Eclipse 编辑器中将 IFile 处理程序获取到活动文件

    我正在准备一个 Eclipse 插件 它检查测试套件中的代码质量 编译器错误 警告 语法检查由默认编译器完成 如果测试代码中出现问题 我们想通知测试套件的开发人员 例如 GOTO 跳转到标签上 这可能会导致无限循环 测试套件非常旧 它们不是
  • 如何使用 QuickCheck 为 StateT 编写测试

    StateT 处于Control Monad Trans State Lazy 里面的函数和m变得更善良使得事情变得困难 LANGUAGE FlexibleContexts import Test QuickCheck newtype St