如何在Haskell中解释callCC?

2023-12-08

在Scheme中执行从a获得的延续call/cc有效地跳回初始调用/抄送并恢复保存的调用堆栈。

我刚刚开始学习 Haskell,我正在尝试弄清楚如何理解callCC。那就是尝试去理解callCC就对方案的理解而言call/cc。实施callCC is

callCC f = cont $ \h -> runCont (f (\a -> cont $ \_ -> h a)) h

据我所知,没有提到任何与保存或恢复的调用堆栈有关的内容。一个人如何解读callCC在 Haskell 中,来自于对 Scheme 的熟悉call/cc.

编辑:也许如果有人可以将以下内容翻译成 Haskell,这将有助于我理解。

(define (f return)
  (return 2)
  3)

(display (f (lambda (x) x))) ; displays 3

(display (call-with-current-continuation f)) ; displays 2

要理解 callCC 在 Haskell 中的含义,您可能想查看它的类型,而不是它的实现:

callCC :: MonadCont m => ((a -> m b) -> m a) -> m a

这里第一个也是最重要的是 MonadCont m。这意味着 callCC 只能在实现 MonadCont 的 monad 中工作——这可能会让您失望,但 IO 不是 MonadCont 的实例。在这方面,callCC 并不像在方案中那样工作。

无论如何,callCC 的参数是((a -> m b) -> m a):这是一个计算,需要(a -> m b) as its参数,这是 callCC 正在捕获的延续。那么让我们尝试编写一些使用 callCC 的东西:

import Control.Monad.Cont
fun _ = return "hi"
main = print $ runCont (callCC fun) id

现在这非常无聊,因为我们不以任何方式使用延续。让我们尝试一下不同的乐趣:

fun' escape = do escape "ahoy"
                 return "die die die"

当您运行代码时,您将看到转义的“调用”永远不会“返回”——它调用了延续,就像在方案中一样。你可能知道“返回”在 Haskell 中不是这样工作的:它不是一个短路操作。您可以认为 callCC 为您提供了一种提前终止计算的方法。

在实现级别上, cont 和 runCont 是与延续传递风格相互转换的函数。您将需要更详细地研究延续单子以了解它的实际工作原理。尝试例如。http://www.haskellforall.com/2012/12/the-continuation-monad.html

(在许多方案实现中,call/cc 也不能真正通过“保存调用堆栈”来工作。如果将程序转换为 CPS,call/cc 就不再是“免费”的东西了。我想你可能会想要阅读例如这个http://www.pipeline.com/~hbaker1/CheneyMTA.html,其中讨论了一种在低级别实施 CPS 的方法。)

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

如何在Haskell中解释callCC? 的相关文章

  • Scheme (Lisp) 中树的深度反转

    我对Scheme中的基本树数据结构进行了深度逆向 define deep reverse t cond null t not pair t t else cons deep reverse cdr t deep reverse car t
  • Data.Array 有多快?

    The 文档 http haskell org ghc docs latest html libraries array 0 3 0 3 Data Array html of Data Array reads Haskell 提供了可索引数
  • 管道 - 将多个来源/生产者合并为一个

    我正在使用读取文件sourceFile 但我还需要在处理操作中引入随机性 我认为最好的方法是拥有一个这样的制片人 Producer m StdGen ByteString 其中 StdGen 用于生成随机数 我打算让生产者执行 source
  • Haskell 中多核编程的现状如何?

    Haskell 中多核编程的现状如何 现在有哪些项目 工具和库可用 有哪些经验报道 2009年至2012年期间 发生了以下事件 2012 从 2012 年开始 并行 Haskell 状态更新开始出现在并行 Haskell 摘要 http w
  • Haskell / cabal 包的解决方法受到 Nix 和 Cabal 的限制?

    我最近开始开发反射平台 https github com reflex frp reflex platform 有一些额外的配置类似于优秀的反射项目骨架 https github com ElvishJerricco reflex proj
  • 为什么我不能声明推断类型?

    我有以下内容 runcount Eq a Num b gt a gt b runcount runcountacc 0 runcountacc Eq a Num b gt b gt a gt b runcountacc n runcount
  • Python 比编译的 Haskell 更快?

    我有一个用 Python 和 Haskell 编写的简单脚本 它读取包含 1 000 000 个换行符分隔的整数的文件 将该文件解析为整数列表 对其进行快速排序 然后将其写入已排序的不同文件中 该文件与未排序的文件具有相同的格式 简单的 这
  • Cabal 无法安装依赖项,但如果直接询问可以安装它们

    我发现 Cabal 反复出现一个非常奇怪的问题 它影响了我获得可重复的 Haskell 构建的能力 我有一个带有沙箱的阴谋集团项目 如果我做cabal install 我收到以下形式的错误 Y failed during the build
  • 来自数据类型的 Haskell 随机数

    我对 Haskell 还很陌生 我有一个数据类型 data Sentence Prop Int No Sentence And Sentence Or Sentence deriving Eq 我已经为它写了一个 Show 实例 然而 无论
  • 在 Haskell 中调试时打印时间戳

    我仍在学习 Haskell 并调试一些函数 并且通常有一个时间戳函数来了解某些操作何时开始和停止 doSomeAction String gt IO doSomeAction arg1 do putStrLn lt lt makeTime
  • Haskell/Idris 中的开放类型级别证明

    在 Idris Haskell 中 可以通过注释类型并使用 GADT 构造函数 例如使用 Vect 来证明数据的属性 但这需要将属性硬编码到类型中 例如 Vect 必须是与 List 不同的类型 是否有可能拥有具有开放属性集的类型 例如同时
  • 函数式语言与语言实现的角度有何不同

    出现了全新的 函数式编程 范式 与过程式编程相比 它需要彻底改变思维模式 它使用高阶函数 纯度 单子等 我们通常在命令式和面向对象语言中不会看到这些 我的问题是如何执行这些语言与命令式或面向对象语言的不同之处在于 例如内存管理或指针等内部结
  • HASKELL:解决河内塔

    下面的代码解决了 hanoi 使用预定义函数 moveLOD swapLOI 和 swapLID 返回移动列表的问题 MoveLOD 将 1 个圆盘从第一个位置移动到三元组第三个位置中的第三个销钉 此外 包含有关运动信息的字符串会堆积在字符
  • GHC 8.4 系列的插件名称查找行为发生变化

    更新 原来这是一个 GHC 错误 现已修复 预计在 8 6 4 版本中发布 https ghc haskell org trac ghc ticket 16104 comment 8 https ghc haskell org trac g
  • monadicIO 的工作原理

    我有以下代码 fastShuffle a gt IO a fastShuffle a
  • 不理解 Monoid 定义中态射的表示法

    我试图理解什么Monoid是从范畴论的角度来看的 但我对用来描述它的符号有点困惑 这是维基百科 在范畴论中 幺半群范畴 C I 中的幺半群 或幺半群对象 M 是一个对象 M 和两个态射 M M M 称为乘法 I M 称为单位 我的困惑在于态
  • 带有参考的 Haskell 数据类型

    我正在实现 Ukkonen 的算法 该算法要求树的所有叶子都包含对同一整数的引用 并且我在 Haskell 中执行此操作是为了了解有关该语言的更多信息 但是 我很难编写出执行此操作的数据类型 Node has children indexe
  • 在不同上下文中使用的多态变量 haskell

    我有以下一段 Haskell 代码 foo Num a gt a gt a gt Either Integer Double gt Either Integer Double foo f x case x of Left i gt Left
  • 如何使用范围内的约束族来证明表达式主体内的实例?

    这是后续我之前的问题 https stackoverflow com questions 70075414 how can i derive typeclass instances from constraint families that
  • 如何给Servant中的所有端点添加前缀?

    我在 Haskell 仆人中有一个 hello world 应用程序 这是其中的一部分 type API my items gt Get JSON MyItem lt gt my items gt Capture id Int gt Get

随机推荐