如何在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? 的相关文章

  • 如何在 Haskell 中枚举递归数据类型?

    这篇博文 http lukepalmer wordpress com 2008 05 02 enumerating a context free language 对于如何使用 Omega monad 对角枚举任意语法有一个有趣的解释 他提
  • 为什么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 但是
  • 向 DrRacket 添加“Simple Scheme”语言

    我想读完这本书 http www eecs berkeley edu bh ss toc2 html http www eecs berkeley edu bh ss toc2 html 但我无法让 简单方案 语言正常工作 该代码将无法运行
  • Haskell 测量函数性能

    在 Haskell 中 我如何 简单地 测量函数的性能 例如 运行需要多长时间 或者需要多少内存 我知道分析 但是 是否有一种更简单的方法不需要我对代码进行太多更改 测量运行需要多长时间以及需要多少内存是两个独立的问题 即 基准测试和分析
  • 如何组合过滤条件

    过滤器类函数接受一个条件 a gt Bool 并在过滤时应用它 当您有多个条件时 使用过滤器的最佳方法是什么 使用了应用函数 liftA2 而不是 liftM2 因为出于某种原因我不明白 liftM2 在纯代码中如何工作 liftM2 组合
  • 方案符号中区分大小写

    据我所知 Scheme 中的符号不 区分大小写 即 eq Hello hello 评估为 t 因为两者都用符号表示 hello 并且scheme具有两个同名符号是同一个对象的属性 然而 这对我来说似乎并非如此 而且事情似乎区分大小写 无论我
  • 有什么方法可以在 do / while / let 块中打印出变量的类型吗?

    有没有办法打印出嵌套变量的推断类型ghci 考虑代码 let f g where g x Int x 那么 最好查询一下类型g e g t f g会打印出Int gt Int 您可以通过给出适当的错误类型注释并检查错误消息来诱骗此信息 Ma
  • 为什么 Haskell 中的点是从右向左排列的?

    如果我们有两个函数 f and g 然后在哈斯克尔h f g相当于h x f g x IE 这些函数从右到左应用于输入 有什么根本原因可以解释为什么它是从右到左 而不是从左到右吗 IE 他们为什么不做h f g相当于h x g f x 反而
  • 将名称绑定到值与将值分配给变量

    阅读 Bartosz Milewski 的文章完整的 https www fpcomplete com school starting with haskell basics of haskell 3 pure functions lazi
  • 没有由文字“1”产生的 Num String 实例

    main do putStrLn myLast 1 2 3 4 myLast a gt a myLast x x myLast xs myLast xs 当我尝试运行此代码时 我收到此消息 没有由文字 1 产生的 Num String 实例
  • Haskell:GHC 无法推断类型。由类型签名错误绑定的刚性类型变量

    我看过几篇主题相似的帖子 但它们并不能真正帮助我解决我的问题 所以我才敢重复 现在我有一个带有签名的函数 run Expr query gt RethinkDBHandle gt query gt IO JSON 这是一个数据库查询运行函数
  • 在一元上下文中使用 Data.Map

    我正在操作的地图具有单子键 类型为IO Double 我需要使用findMax在这张地图上 我可以用吗liftM为了这 Map findMax Map fromList f x X f y Y f z Z Here f x有类型IO Dou
  • Haskell cabal:我刚刚安装了软件包,但现在找不到软件包

    在这里 http haskell org haskellwiki Cabal Install I just installed packages 2C but now the packages are not found这是我可以找到我正在
  • 在 Haskell 中创建 100 万个线程需要多长时间?

    据我了解 Haskell 有绿色线程 但它们的重量有多轻 是否可以创建100万个线程 或者 100 000 个线程需要多长时间 from here http www reddit com r programming comments a4n
  • 为什么我不能将 Int 类型与 a 类型匹配

    哈斯克尔新手在这里 我在这里尝试做的事情的一个过于简单的例子 test Int gt a test i i Couldn t match expected type a with actual type Int a is a rigid t
  • 用纯函数式语言保持状态

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

    所以我在方案中编程并创建了一个删除重复项的函数 但它不适用于嵌套 我真的想不出一个好方法来做到这一点 有没有办法修改我当前的代码并简单地使其与嵌套一起工作 清单 这是我的代码 define duplicates L cond null L
  • 系统地将函数应用于 haskell 记录的所有字段

    我有一条包含不同类型字段的记录 以及一个适用于所有这些类型的函数 举一个小 愚蠢 的例子 data Rec Rec flnum Float intnum Int deriving Show 比如说 我想定义一个为每个字段添加两条记录的函数
  • 最好的Scheme解释器或编译器是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • `arr fst` 是如何自然变换的?

    I asked 这个问题 https stackoverflow com q 62733726 11143763不久以前 这是关于以下箭头定律 arr fst first f f arr fst Category k gt k b c gt

随机推荐