在 monad 转换器类型类中使用列表 monad?

2024-05-18

我的目标是创建一个在 ReaderT WriterT 堆栈或 RWS 堆栈中使用列表 monad 的函数。更一般地说,如何在 mtl 类型类(例如 MonadReader、MonadWriter)中使用列表 monad?

我为什么要尝试这样做?这个问题是一个练习哈斯克尔入门 http://www.apress.com/9781430262503。它要求我“使用 MonadReader 和 MonadWriter 的功能来包装基本列表 monad。要检查该功能是否通用,请使用两个不同的 monad 来[测试]所请求的功能:ReaderT r (WriterT w []) a and RWST r w s m a“所以这本书暗示这是可能的。

我不知道如何“告诉”编译器使用列表单子。如果我使用ask >>= lift or ask >>= lift . lift我可以获得 2 级堆栈(RWST []) 或 3 级堆栈 (ReaderT WriterT [])工作,但不能两者兼而有之。

我的问题重点:

pathImplicitStack' start end | start == end = tell [end]
pathImplicitStack' start end =
  do  (s0, e0) <- ask >>= lift
      guard $ s0 == start
      tell [start]
      pathImplicitStack' e0 end

另外,我想知道如何输入该函数。到目前为止我最好的尝试看起来像pathImplicitStack' :: (MonadReader [(Int, Int)] m, MonadWriter [Int] m, MonadPlus m) => Int -> Int -> m ()我知道这是不对的,列表单子可能丢失了。另外,我认为 MonadPlus 在类型签名中可能有用,但我不太确定。

这行:do (s0, e0) <- ask >>= lift是那个给我带来麻烦的人。我尝试了 0、1、2 次电梯,但都没有成功。我想ask for a [(Int, Int)]然后使用列表 monad 来处理(Int, Int)(并让列表单子为我尝试所有可能性)。

作为练习的一部分,我需要能够调用pathImplicitStack'具有这两个功能(或非常相似的功能):

pathImplicitRW :: [(Int, Int)] -> Int -> Int -> [[Int]]
pathImplicitRW edges start end = execWriterT rdr
  where rdr = runReaderT (pathImplicitStack' start end) edges :: WriterT [Int] [] ()

pathImplicitRWS :: [(Int, Int)] -> Int -> Int -> [[Int]]
pathImplicitRWS edges start end = map snd exec
  where exec = execRWST (pathImplicitStack' start end) edges ()

这与我之前的问题有关:如何在 ReaderT 中使用列表 monad? https://stackoverflow.com/questions/24178800/how-do-i-use-list-monad-inside-of-readert

整个文件方便测试:

{-# LANGUAGE FlexibleContexts #-}

module Foo where

import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.RWS

graph1 :: [(Int, Int)]
graph1 = [(2013,501),(2013,1004),(501,2558),(1004,2558)]


pathImplicitRW :: [(Int, Int)] -> Int -> Int -> [[Int]]
pathImplicitRW edges start end = execWriterT rdr
  where rdr = runReaderT (pathImplicitStack' start end) edges :: WriterT [Int] [] ()

pathImplicitRWS :: [(Int, Int)] -> Int -> Int -> [[Int]]
pathImplicitRWS edges start end = map snd exec
  where exec = execRWST (pathImplicitStack' start end) edges ()

pathImplicitStack' :: (MonadReader [(Int, Int)] m, MonadWriter [Int] m, MonadPlus m) => Int -> Int -> [m ()]
pathImplicitStack' start end | start == end = tell [end]
pathImplicitStack' start end =
  do  (s0, e0) <- ask >>= lift
      guard $ s0 == start
      tell [start]
      pathImplicitStack' e0 end

edit

根据约翰·L的反馈我尝试过

pathImplicitStack' :: (MonadReader [(Int, Int)] (t []), MonadWriter [Int] (t []), MonadPlus (t []), MonadTrans t) => Int -> Int -> t [] ()
pathImplicitStack' start end | start == end = tell [end]
pathImplicitStack' start end =
  do  (s0, e0) <- ask >>= lift
      guard $ s0 == start
      tell [start]
      pathImplicitStack' e0 end

但正如他指出的,它只能与一个 monad 转换器一起使用来包装列表 monad,即 RSWT,并且不能与 ReaderT WriterT 一起使用。所以这不是我正在寻找的解决方案。


因此,在问题的要求范围内执行此操作的基本问题是,没有 MTL 库函数可用于从可能任意级别向下的列表 monad 中提升。然而,你可以“作弊”一点:MonadPlus合并的实例Monad is无论深度如何,都从底层列表 monad 继承,您可以使用它来生成所需的操作:

  do  (s0, e0) <- ask >>= msum . map return

然后类型签名也有错误,需要修改为:

pathImplicitStack' :: (MonadReader [(Int, Int)] m, MonadWriter [Int] m, MonadPlus m) => Int -> Int -> m ()

编辑:实际上转念一想,这实际上并不是作弊。它只是使用MonadPlus用于链接替代操作的 API,而不是直接使用底层列表 monad。

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

在 monad 转换器类型类中使用列表 monad? 的相关文章

  • 绑定变量时 Haskell 中的无限循环

    下面的 Haskell 代码不会终止 有人可以解释一下为什么吗 谢谢 f let x 10 in let x x x in x 我认为解释器首先绑定 x 10 然后将 x x 计算为 100 并绑定 x 100 环境变为 x 100 那么整
  • 在生成此 SOP 函数时,如何修复类型错误,包括“无法对 Traversable 进行量化”?

    我只是说我什至不确定这是否可能 这是迄今为止我在 Haskell 中尝试过的最通用的事情 我正在尝试制作一个更通用的版本applyFunc在发现https stackoverflow com a 58890226 3096687 https
  • 应用交换律

    带有效果的应用程序编程 http staff city ac uk ross papers Applicative html麦克布莱德和帕特森的论文提出了互换法 u lt gt pure x pure f gt f x lt gt u 为了
  • 无法通过 cabal 安装“System.Random”

    我尝试通过 Cabal 通过 Powershell 和 Git Bash 安装 System Random 得到这个结果 PS C Users xxx gt cabal install random Resolving dependenci
  • 计算/获取分层数据的“级别”

    好吧 我真的不知道这是否是正确的标题 但我不知道如何称呼它 我的问题是关于我的作业 我现在已经工作了几个小时 主题是 函数式数据结构 我有点陷入困境 我不知道如何继续 所以我需要编写一个具有以下签名的函数 data Heap e t Hea
  • 如何在 blaze-html 中渲染 blaze-svg 标记

    我想将使用 blaze svg 生成的 svg 图直接包含在使用 blaze html 生成的 html 中 两者都基于 blaze markup 所以我希望它很容易 diagram1 Svg diagram1 try1 Html try1
  • 可以通过Data.Function.fix来表达变形吗?

    我有这个可爱的fixana这里的函数执行速度比她的姐妹快 5 倍左右ana 我有一个criterion报告支持我这一点 ana alg Fix fmap ana alg alg fixana alg fix f gt Fix fmap f
  • 如何、为什么以及何时使用“.Internal”模块模式?

    我在上面看到了几个包裹hackage http hackage haskell org packages archive pkg list html其中包含模块名称 Internal作为他们的姓氏组成部分 例如Data ByteString
  • 'lens' 的阴谋集团依赖性解析失败

    我刚刚做了一个阴谋更新并尝试从 hackage 安装 lens 这给了我以下错误 cabal install j lens Resolving dependencies Configuring dlist 0 7 0 1
  • 我应该使用镜头中的什么来按索引构建只读吸气剂?

    我有一个内部细节被隐藏的类型 我想提供某种镜头 可以在特定索引处读取所述类型的元素 但是not修改它们 一个Ixed我的类型的实例似乎没有做我想要的事情 因为它明确允许修改 尽管不允许插入或删除 如果我想允许只读索引 我不确定我使用什么 如
  • 对元组列表进行排序的函数 - Haskell

    抱歉 这个简单的问题只是我对 haskell 非常陌生 我正在尝试编写一个函数 order 它将对另一个函数 Frequency 生成的元组列表进行排序 频率计算列表中不同元素的数量 a给出一个这样的结果 比如 gt 频率 aabbbccc
  • 为什么 exceptT 没有 MonadMask 实例?

    爱德华 克梅特例外情况图书馆不提供单子掩码 https www stackage org haddock lts 7 18 exceptions 0 8 3 Control Monad Catch html t MonadMask实例为Ex
  • 什么是阴谋地狱?

    在阅读有关 阴谋地狱 的内容时 我有点困惑 因为这个词的含义太多了 我猜最初 Cabal Hell 指的是钻石依赖问题 该问题是通过限制构建计划在每个构建计划中只有任何包的单个版本来解决的 一个包的两个不同版本不能存在于单个构建计划中 正如
  • 有什么方法可以在 do / while / let 块中打印出变量的类型吗?

    有没有办法打印出嵌套变量的推断类型ghci 考虑代码 let f g where g x Int x 那么 最好查询一下类型g e g t f g会打印出Int gt Int 您可以通过给出适当的错误类型注释并检查错误消息来诱骗此信息 Ma
  • Parsec 函数“parse”和类“Stream”的类型签名

    约束条件是什么 Stream s Identity t 下面的类型声明是什么意思 parse Stream s Identity t gt Parsec s a gt SourceName gt s gt Either ParseError
  • 是否有适用于 Haskell 或 Scala 等函数式语言的 LL 解析器生成器?

    我注意到明显缺乏用函数式语言创建解析器的 LL 解析器 我一直在寻找但没有成功的理想发现是为 ANTLR 风格的 LL 语法生成 Haskell 解析器 语法的模小数重新格式化 并且令我惊讶的是 每个最后一个解析器生成器都具有函数我发现的语
  • 为什么我不能将 Int 类型与 a 类型匹配

    哈斯克尔新手在这里 我在这里尝试做的事情的一个过于简单的例子 test Int gt a test i i Couldn t match expected type a with actual type Int a is a rigid t
  • Haskell 中的所有图形和 Web 库是如何实现的?

    我才开始学习Haskell 我读到它是一种纯函数式语言 其中的所有内容都是不可变的 因此 输入输出 写入和读取数据库之类的事情会导致状态的可变性 我知道 Haskell 中有一种叫做 monad 的东西 它允许在 Haskell 中使用命令
  • 为什么 Haskell (Hugs) 中的 Show 实例会导致堆栈溢出错误?

    下面是 Haskell 中的多态数据类型 由 Hugs 解释 我正在尝试创建一个 Show for Equality 的实例 实例声明表示 如果类型 a 在 Show 中 则相等 a 在 Show 中 它应该以 a b 的形式打印构造函数
  • 用纯函数式语言保持状态

    我正在尝试弄清楚如何执行以下操作 假设您正在开发直流电机的控制器 您希望让它以用户设置的特定速度旋转 def set point ref sp 90 while true let curr read speed controller set

随机推荐

  • 如何使用基于时间的触发器每小时运行一个脚本,仅在工作日的整点运行?

    我只需要在工作日每小时运行一个 Google App Script 脚本 两者之一似乎很容易做到 但将其结合起来我不确定 每小时触发 ScriptApp newTrigger RefreshRates timeBased inTimezon
  • 使用一个 apk 安装两个应用程序

    我有 2 个应用程序 1 内容提供者 2 使用此 ContentProvider 的应用程序 我需要使用单个 apk 文件安装这 2 个应用程序 我想在 Eclipse 中同时推送这两个应用程序 如果我将另一个项目添加到一个应用程序的构建路
  • 让协程等待之前的调用

    我还没有完全掌握 Kotlin 协程 基本上我希望协程在执行之前等待任何先前的调用完成 下面的代码似乎可以工作 但它正在做我认为它正在做的事情吗 private var saveJob Job null fun save saveJob s
  • Java递归方法求阶乘返回负输出[重复]

    这个问题在这里已经有答案了 我知道这是溢出 但问题是 20 是相对较小的数字 这不应该发生 对吧 有没有更好的方法来查找大数 例如 1000 的阶乘 而不会得到这种奇怪的结果 public class RecursiveFunctionsE
  • 更新序列化器时,嵌套序列化器没有实例(many = true)

    我有 UserSerializer 和嵌套的 UserClientSerializer 我正在尝试更新已登录用户的信息 但我收到 unique together 验证错误 我有以下型号 模型 py class UserClients mod
  • 迭代字典按排序顺序返回键

    我有一个关于 python 如何处理字典中的数据的问题 假设我有一个简单的字典 其中一个数字作为键 一个数字作为值 如下所示 a 5 3 20 1 1 1 5 2 100 3 11 6 14 1 15 2 16 4 17 2 25 1 19
  • AngularJS - 关闭模态窗口

    我的内容包括 bootstrap css getbootstrap com 2 3 2 angular ui bootstrap tpls 0 10 0 min js from angular ui github io bootstrap
  • 什么是 Microsoft.Bcl.Async?

    什么是 Microsoft Bcl Async 它的用途是什么 我已经读过包装页面 https www nuget org packages Microsoft Bcl Async that 此包使 Visual Studio 2012 项
  • Express中间件修改请求

    我目前有一个正在运行的服务器 前端使用nodejs mongo express 和 W2UI W2ui 请求来自包含所有参数的记录数组 记录 名称 foo 我想编写一个中间件 在请求到达路由之前对其进行编辑和更改 您可以创建自己的中间件来处
  • 如何使用 ASP.NET Web API 生成 ATOM 和 RSS2 提要?

    需要采取哪些步骤来调整 ASP NET Web API 的默认 XML 输出以生成 ATOM 和 RSS2 提要 您将需要实现自定义 MediaTypeFormatter 您可能想查看 Filip 的博客文章用于 ASP NET WebAP
  • Bootstrap 中的旋转字形 / Font Awesome

    我试图让引导站点中的字形在悬停时旋转 除了更改颜色之外 这是我的尝试 http jsfiddle net young greedo17 88g5P http jsfiddle net young greedo17 88g5P 使用此代码 d
  • 获取 Parse Analytics 自定义仪表板

    是否可以使用 Javascript 或 REST API 从 Parse 获取应用程序分析 我想在我自己的仪表板中显示下载数量和自定义事件 不可以 您只能通过 REST API 推送 https parse com docs rest ht
  • 使用绝对定位时文本被破坏

    我有一个小挑战 我在 Stack Overflow 上没有找到任何解决方案 这就是我得到的 这就是我想要的 为了产生这个标题效果 我使用绝对位置 我什至不知道我的标题的宽度和高度 因此 使用此解决方案时 大文本会中断 My HTML div
  • Boost.Asio 段错误,不知道为什么

    这是我的 Boost Asio 项目基于示例的 SSCCE 我花了大约一个小时才找到这个错误 include
  • 在空手道 DSL 功能文件中使用模拟并独立运行

    我有 REST 服务 用不同于 Java 的语言编写 它与其他 REST 服务几乎没有依赖关系 例如正在开发和测试的服务是A 其他服务分别是B and C 我想运行系统测试A 一些测试需要B or and C在线并执行查询A 我编写了 b
  • 将 Array Obj-c 的内容转储到控制台

    我寻找了如何转储和数组到我主要找到的控制台 for id name in arrayStuff NSLog Array contents d name 我尝试了不同的格式化程序 d g 等 它们确实打印了不同的内容 但不是我 99 确信被输
  • Python LocationValueError:未指定主机

    自从上次更新我的 Windows 以来 我的 python 无法连接到互联网 当我 pip 某些东西时 错误就像 if host startswith AttributeError NoneType object has no attrib
  • PHP、jQuery 和 Ajax 调用乱序

    我正在使用 jQuery 进行 Ajax 调用 我有 x 数量的 Ajax 调用附加到 div 这些 Ajax 加载请求是由 PHP foreach 循环生成的 问题是它们渲染的顺序不正确 它们被设置在数组中
  • Android 应用程序在启动时打开应用程序信息屏幕,而不是启动主 Activity

    我不确定这是否是一个问题 但这是我第一次遇到这个问题 我正在开发一个应用程序 当我在进行一些编码后断开应用程序与 Android Studio 和 PC 的连接时 如果我尝试在手机上打开应用程序 它会启动app info屏幕 我们看到强制停
  • 在 monad 转换器类型类中使用列表 monad?

    我的目标是创建一个在 ReaderT WriterT 堆栈或 RWS 堆栈中使用列表 monad 的函数 更一般地说 如何在 mtl 类型类 例如 MonadReader MonadWriter 中使用列表 monad 我为什么要尝试这样做