连续单子转变

2024-03-28

在尝试为 ContT monad 转换器建立一些直觉时,我(也许并不奇怪)发现自己很困惑。问题在于 shiftT 操作似乎没有做任何有用的事情。

首先是一个如何使用它的简单示例

shiftT $ \famr -> lift $ do
  a <- calculateAFromEnvironment
  famr a

famr a可以是一些更复杂的表达式,只要它返回一些m r。现在尝试解释我的直觉,shiftT 并没有添加任何内容:

-- inline shiftT
ContT (\f2 -> evalContT ((\f1 -> lift (do
  a <- calculateAFromEnvironment
  f1 a)) f2))

-- beta reduction
ContT (\f2 -> evalContT (lift (do
  a <- calculateAFromEnvironment
  f2 a)))

-- inline evalConT
ContT (\f2 -> runContT (lift (do
  a <- calculateAFromEnvironment
  f2 a)) return)

-- inline lift
ContT (\f2 -> runContT (ContT (\f3 -> (do
  a <- calculateAFromEnvironment
  f2 a) >>= f3)) return)

-- apply runConT
ContT (\f2 -> (\f3 -> (do
  a <- calculateAFromEnvironment
  f2 a) >>= f3) return)

-- beta reduce
ContT (\f2 -> (do
  a <- calculateAFromEnvironment
  f2 a) >>= return)

-- (>>= return) is identity
ContT $ \f2 -> do
  a <- calculateAFromEnvironment
  f2 a

事实证明我们可以直接构建 ContT。

提问时间:是否存在shift/shift在cont/ContacT之上添加任何内容的情况?或者它们只是用来使代码更具可读性?


After by 古尔肯格拉斯 https://stackoverflow.com/users/5318306/gurkenglas我发现的建议这个很好的解释 https://github.com/renormalist/pugs/blob/f09558ae9b5ef2cbab75110abc1cb385931329cc/src/Pugs/AST/Eval.hs#L27 of shiftT and resetT带有用法、动机和语义的示例!

这些功能非常简单。他们的定义在transformers http://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Monad-Trans-Cont.html#v:shiftT库很简单:

resetT :: (Monad m) => ContT r m r -> ContT r' m r
resetT = lift . evalContT

shiftT :: (Monad m) => ((a -> m r) -> ContT r m r) -> ContT r m a
shiftT f = ContT (evalContT . f)

但哲学和意义远远落后于一些直观的理解。所以我建议您阅读上面链接中的解释。有时,很容易定义的事情实际上可以做一些复杂的事情。

根据上面链接的 pugs 中的解释改编的文档:

shiftT

shiftT就好像callCC,除了当您激活延续时 由...提供shiftT,它将运行到最近的封闭的末尾resetT, 然后跳回到您激活延续的点之后。 请注意,因为控制最终返回到 子延续已激活,您可以在中多次激活它 同一个块。这与callCC的延续,丢弃当前的 激活时的执行路径。

See resetT有关这些分隔子延续实际上如何的示例 工作。

resetT

创建一个范围shiftT的子延续最终保证 退出结束。考虑这个例子:

resetT $ do
    alfa
    bravo
    x <- shiftT $ \esc -> do   -- note: esc :: m Int, not a ContT
       charlie
       lift $ esc 1
       delta
       lift $ esc 2
       return 0
    zulu x

这会:

  1. Perform alfa

  2. Perform bravo

  3. Perform charlie

  4. Bind x为 1,从而执行zulu 1

  5. 从末端掉下来resetT,然后跳回到刚刚之后esc 1

  6. Perform delta

  7. Bind x到 2,从而执行zulu 2

  8. 从末端掉下来resetT,然后跳回到刚刚之后esc 2

  9. 逃离resetT,导致其产量为 0

因此,不同于callCC的延续,这些子延续最终将 在它们被激活后返回到点,在从末端掉落后 最近的resetT.

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

连续单子转变 的相关文章

  • 不同种类的ReaderT?

    冒着成为一个XY问题 https en wikipedia org wiki XY problem 是否有可能有一个ReaderT与不同的环境 我正在尝试类似 type AppM perms ReaderT perms IO 但是编译器抱怨
  • 尝试以特殊行为渲染 Threepenny-gui 中的字段

    我想要做的是设置字段 当它们处于焦点时显示详细信息 而当它们不处于焦点时显示摘要 例如 A 当它失去焦点 变得模糊 时 我将值保存在 状态 映射中 然后将该值更改为旧值的函数 即汇总值 b 当它获得焦点时 我用我在地图中保存的旧值替换摘要值
  • 什么时候可以将函数绑定到另一个名称?

    在解释器中工作时 将函数绑定到名称通常很方便 例如 ghci gt let f 1 ghci gt f 1 2 这是别名f到函数 1 简单的 然而 这并不总是有效 我发现导致错误的一个例子是尝试使用别名nub来自Data List模块 例如
  • 如何将“-ddump-minimal-imports”与堆栈一起使用

    我是 stack 的忠实粉丝 我已经从我的机器中完全删除了任何独立的 cabal 和 ghc 可执行文件 让 stack 在它自己神秘的 stack 目录中安装它需要的任何东西 但是 看起来有些标志在堆栈下无法正常工作 例如 我想使用 dd
  • 作用域类型变量需要显式 foralls。为什么?

    如果你想使用 GHC词法作用域类型变量 http www haskell org ghc docs 7 6 2 html users guide other type extensions html scoped type variable
  • 何时使用 STRef 或 IORef?

    STRef 和 IORef 之间到底有什么区别 何时使用它们 据我所知 它们都是可变状态 那么它们存在的意义是什么 您可以在其中做更多事情IO单子比ST单子 后者提供可变引用 前者提供可变引用 异常捕获 线程 当然还有IO 使用可以解决问题
  • Haskell - 无法将类型“PersistEntityBackend record0”与“SqlBackend”匹配

    我正在尝试通过 Yesod 中的 id 获取记录 我的代码是 getEditActorR Handler Html getEditActorR do actorId lt runInputGet ireq intField id actor
  • Haskell 错误:“非详尽模式”

    所以我有这个功能 当我尝试像这样使用它时 合并排序列表 1 1 1 1 它给了我一个错误 1 1 例外 SortFunctions hs 86 1 91 89 非详尽 函数 mergeSortedLists 中的模式 85 mergeSor
  • 为什么 Haskell 类型签名声明有多个箭头?

    抱歉 这句话措辞不好 但很难描述 我想我会跳到这个例子 add Integer gt Integer gt Integer add x y x y 为什么 Integer gt Integer gt Integer 代替 Integer I
  • 如何根据列表中的先前值过滤Haskell中的列表元素?

    我正在努力在 Haskell 中创建一个函数 该函数根据列表中前一个元素的条件过滤列表的数字 Example 前一个数字是 2 的倍数 myFunction 1 2 5 6 3 expected output 5 3 我知道如何申请filt
  • 如何在 Windows 7 中配置 cabal?

    我已经在Windows 7中安装了Haskell Platform 2012 我在控制台中编写cabal update我收到消息说有新版本的阴谋集团 我写的cabal install cabal install 安装完成后 它告诉我 cab
  • 在 Haskell 中将 Maybe Int 转换为 Int

    我正在编写以下代码 并希望找到框字符串中数字的索引 所以我用了findIndex但它返回Maybe Int值 而我只想要Int value 我怎样才能转换Maybe Int to Int值或者有什么方法可以提取Int from Maybe
  • 移动列表中特定元素的简单函数

    我是 Haskell 的新手 我正在尝试弄清楚如何创建一个函数 shift Eq a gt a gt a gt Int gt a shift x h t z 输入 一个通用列表和一个相同类型的元素 x 前提条件 元素x存在于列表中 Outp
  • 使用通用元组函数一次进行多次折叠

    如何编写一个接受类型函数元组的函数ai gt b gt ai并返回一个函数 该函数接受类型元素的元组ai 类型的一个元素b 并将每个元素组合成一个新的元组ai 那是签名应该是这样的 f a1 gt b gt a1 a2 gt b gt a2
  • GHC 可以为 monad 转换器派生 Functor 和 Applicative 实例吗?

    我正在尝试实施MaybeT本着mtl图书馆 使用这个非编译解决方案 LANGUAGE FlexibleInstances MultiParamTypeClasses UndecidableInstances import Control M
  • 我可以获得有关过度限制类型签名的警告吗?

    当我为可能更具多态性的函数提供类型签名时 GHC 或某些 lint 工具可以告诉我吗 GHC 不这样做 快速搜索 Hackage 也没有发现任何结果 实现这样的事情的一个简单但可能非常有效的方法是在 GHCi 中加载模块 使用 browse
  • 如何使用 Haskell 中的 thyme 库从 Int 值创建 UTCTime?

    我有年 月 日 小时和分钟值 所有这些都是类型Int 我怎样才能将它们转换为UTCTime or UniversalTime 需要导入以下内容 import Control Lens import Data Thyme Clock impo
  • 导入 Haskell 模块

    我是哈斯克尔的新手 为什么当我尝试使用时Days from Data Time我收到此错误 Could not find module Data Time It is a member of the hidden package time
  • 如何为强制长度为 2^n 的向量类型定义可用的 Applicative 实例

    对于某些应用程序 我需要长度为 2 n 的向量 为了强制某些操作的长度匹配 我使用 ist 应用实例定义了我的类型 如下所示 LANGUAGE GADTs DataKinds FlexibleInstances FlexibleContex
  • Haskell 中的实例声明

    我有这两个功能 primes sieve 2 where sieve p xs p sieve x x lt xs x mod p gt 0 isPrime number number 1 null x x lt takeWhile x g

随机推荐

  • jQuery:一年中的一周脚本正在运行

    不久前我需要一个脚本来每周更新一些内容 我的问题在这个论坛 https stackoverflow com questions 3701276 jquery update content every week or long period
  • CMS 软件中的空白 index.html 而不是 .htaccess

    我注意到 Joomla Wordpress 和其他 CMS 在其所有子文件夹中都有空白的 index html 文件 以防止人们窥视文件夹结构 我的问题是为什么他们不能禁止使用 htaccess 文件查看文件夹 而不是将空白的 index
  • 多个 goroutine 的 Go 内存消耗

    我试图检查 Go 在 100 000 个 goroutine 上的表现如何 我编写了一个简单的程序来生成许多例程 除了打印一些公告之外什么也不做 我将 MaxStack 大小限制为仅 512 字节 但我注意到程序大小并没有随之减小 它消耗了
  • 从运行脚本阶段获取当前方案名称

    有没有办法从运行脚本阶段获取当前方案 我试过了 SCHEME NAME 但它不存在 我找不到要使用的环境变量 因此我必须开发一种解决方法 将方案名称写入磁盘建立预行动然后将其读回运行脚本 phase 对于您感兴趣的每个方案 请访问编辑方案并
  • LibGDX:如何使平铺地图图块可点击?

    如何为平铺地图中的图块添加点击侦听器 以便当您用鼠标选择图块时它会突出显示 libGDX 不直接支持这一点 因为 TiledMap 内容仅用于渲染 您可以轻松创建一个Stage不过 它将充当 TiledMap 的某种覆盖输入层 只需创建一个
  • 线程中的 GLib GMainContext?

    我在堆栈溢出上搜索以找到与我的问题相关的答案 但我没有找到任何答案 我有一个启动线程的主线程 我的 main 函数 新线程运行 GMainLoop 在我的主要功能中 我不断通过调用添加源g io watch一些文件描述符 但如果事件被调度
  • Python 日志记录和子进程输出以及错误流

    我想启动一个 python 进程并将子进程错误消息记录到父脚本的日志记录对象中 理想情况下 我希望将日志流统一到一个文件中 我可以以某种方式访问 日志记录类的输出流吗 我知道的一种解决方案是使用 proc log 进行日志记录 正如下面的答
  • 如何每天在特定时间触发 akka 调度程序?

    我创建了一个 Akka 的调度程序 每天在固定时间发送邮件 例如每天上午 6 00 那么如何称呼演员呢 我的意思是我应该使用什么逻辑 谢谢 只需计算现在和接下来的下午 6 点之间的差异 将其作为初始延迟 然后每 24 小时重复一次
  • Rails 5 - 在编辑操作中使用范围来查找特定实例的相关子项

    我正在尝试学习如何在 Rails 5 应用程序中使用范围 我问了一个背景问题here https stackoverflow com questions 41755032 rails 5 exclude specific instances
  • 在 React 中专注于 div,无需单击即可在模块上启用键盘导航

    我正在 React 中从头开始编写一个图像库 当单击图像时 会弹出一个模式 与我的库组件分开的组件 我想要使用左右箭头在图片之间导航 不仅仅是屏幕上添加的箭头 onclick 但目前它只关注当我单击一次时的模式 然后我也可以使用键盘导航 o
  • AWS - cfn-init 不创建文件

    我是云信息新手 我正在使用 cfn init 创建文件 但不会创建文件 我的堆栈也不会失败 使用 EC2 实例等所需资源成功创建堆栈 它还会安装 AWS CLI 如用户数据中所述 但它只是不创建我希望创建的文件 我尝试使用不允许回滚堆栈的高
  • 测试 RESTful 服务的方法? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想直接通过 HTTP 测试我的 RESTful 应用程序 并且我正在寻找可以帮助我完成该任务的工具 基本上我正在寻找一个简单的 HTTP 请求包装器
  • 我是否需要告诉 Apache Tomcat 保持 Websocket 连接打开?

    我正在尝试Apache Tomcat Websocket 实现 http tomcat apache org tomcat 7 0 doc web socket howto html 问题是 连接总是在最多 30 秒的空闲时间后关闭 我是否
  • 通过 DataMapper 来自 SQLite 内存数据库的 No Such Table 错误

    我有一个 Ruby 程序 它使用 DataMapper 作为 ORM 与内存中的 SQLite DB 进行通信 这一直工作得很好 但是我最近刚刚添加了一个新的 DM 类和相应的表 令我惊讶的是 现在在 auto migrate 过程中事情发
  • 内存保护的最新技术水平如何?

    我对 C 语言 指针和内存管理等低级语言了解得越多 我就越想了解现代操作系统和内存保护的最新技术水平 例如 采取了哪些检查来防止某些恶意程序随机尝试读取尽可能多的地址空间并忽略操作系统设置的规则 一般来说 这些内存保护方案是如何工作的 他们
  • C# Microsoft Graph - 如何从 msal-browser 发送带有访问令牌的电子邮件

    我正在使用 C Microsoft Graph 发送电子邮件 但当我调用等待 graphClient Me SendMail message Request PostAsync 时 我遇到错误 对象引用未设置到对象的实例 方法 我尝试首先调
  • 如何找到ZedGraph上的索引位置

    有没有办法根据当前的 xPosition 找到曲线的索引位置 假设我有一个曲线项目 MyCurve 它有 20k 点 当鼠标移动时我可以获得鼠标位置 然后只需使用以下函数即可获得 x 和 y 位置 double xPos 0 yPos 0
  • 错误 lnk2005 已在 .obj 中定义

    关于这个错误有很多疑问 但它们只与一个变量相关 test h namespace World enum Objects TERRAIN 1 BOX 2 SPHERE 4 CAPSULE 8 void WorldObjects2 unsign
  • 如何将 SQL 结果集限制为不太常见的项目

    问题 我有一份姓名和地址列表 有些姓名 人 与其他姓名 人 具有相同的地址 街道 邮政编码 城镇 我想选择所有这些名称 其地址出现次数不超过三次 并从其余名称中选择前三个名称 每个名称都指向同一地址 例子 Albert Adr1 Berta
  • 连续单子转变

    在尝试为 ContT monad 转换器建立一些直觉时 我 也许并不奇怪 发现自己很困惑 问题在于 shiftT 操作似乎没有做任何有用的事情 首先是一个如何使用它的简单示例 shiftT famr gt lift do a lt calc