使用 MonadRef 实现 MonadCont

2024-04-08

有一个众所周知的问题我们不能使用forall类型在Cont返回类型 https://stackoverflow.com/questions/7178919/how-to-make-callcc-more-dynamic/7180154#7180154.

不过,有以下定义应该没问题:

class Monad m => MonadCont' m where
    callCC' :: ((a -> forall b. m b) -> m a) -> m a
    shift :: (forall r.(a -> m r) -> m r) -> m a
    reset :: m a -> m a

然后找到一个有意义的例子。在这张纸 http://www.carlssonia.org/ogi/mdo-callcc.pdf作者声称我们可以实施MonadFix在之上ContT r m提供了m实施的MonadFix and MonadRef。但我认为如果我们确实有一个MonadRef我们实际上可以实现callCC'上面就像下面这样:

--satisfy law: mzero >>= f === mzero
class Monad m => MonadZero m where
    mzero :: m a

instance (MonadZero m, MonadRef r m) => MonadCont' m where
    callCC' k = do
        ref <- newRef Nothing
        v <- k (\a -> writeRef ref (Just a) >> mzero)
        r <- readRef ref
        return $ maybe v id r
    shift = ...
    reset = ...

(不幸的是我不熟悉语义shift and reset所以我没有为他们提供实现)

这个实现对我来说似乎没问题。直观地讲,当callCC'被召唤,我们喂养k其自身效果总是失败的函数(尽管我们无法提供任意类型的值b,但我们总能提供mzero类型的m b并且根据法律,它应该有效地停止计算所有进一步的影响),并且它捕获接收到的值作为最终结果callCC'.

所以我的问题是:

此实现是否按理想的预期工作callCC?我们可以实施吗shift and reset也有正确的语义吗?

除了上述内容之外,我还想知道:

为了确保正确的行为,我们必须假设以下属性MonadRef。那么法律会怎样规定MonadRef为了使上述实现按预期运行?

UPDATE

事实证明,上述简单的实现还不够好。使其满足“持续电流”

callCC $\k -> k m === callCC $ const m === m

我们必须调整实施

instance (MonadPlus m, MonadRef r m) => MonadCont' m where
    callCC' k = do 
       ref <- newRef mzero
       mplus (k $ \a -> writeRef ref (return a) >> mzero) (join (readRef ref))

换句话说,原来的MonadZero还不够,我们必须能够结合mzero值与正常计算而不取消整个计算。

以上并没有回答问题,只是由于最初的尝试被伪造为候选人而进行了调整。但对于更新后的版本来说,原来的问题仍然是问题。尤其,reset and shift仍有待实施。


(这还不是答案,但我脑海中只出现了一些线索。我希望这将导致我自己或其他人真正的答案。)

按值调用与按名称调用是双重的 http://homepages.inf.ed.ac.uk/wadler/papers/dual/dual.pdf——菲利普·瓦德勒

在上面的论文中,作者介绍了“对偶演算”,一种与经典逻辑相对应的类型演算。在最后一节中,有一段说

按需呼叫的双重策略可以 通过用余值覆盖余项来避免这种低效率 第一次评价。

正如 Wadler 的论文中所述,按名称调用急切地评估延续(它在评估所有值之前返回),而按值调用延迟评估延续(它仅在评估所有值之后返回)。

现在,看一下callCC'上面,我相信这是延续侧按需调用的双重示例。评估的策略是为给定的函数提供一个假的“延续”,但缓存此时的状态以便稍后调用“真实”的延续。这在某种程度上类似于对延续进行缓存,因此一旦计算完成,我们就恢复该延续。但缓存评估值就是按需调用的意思。

一般来说,我怀疑状态(截至当前时间点的计算)与延续(未来的计算)是对偶的。这将解释一些现象。如果这是真的,那就不足为奇了MonadRef(对应于全局和多态状态)是对偶的MoncadCont(对应于全局和多态延续),因此它们可以用来相互实现。

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

使用 MonadRef 实现 MonadCont 的相关文章

  • 在 Haskell 中编写 Web 应用程序的最简单方法是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在我的项目中更多地使用 Haskell 并且我认为如果我可以开始将它用于 Web 应用程序 这将真正
  • 从 createProcess 外部获取的句柄读取

    我正在尝试创建一个进程 并通过我在外部提供的句柄与其进行通信createProcess功能 stdOutH lt openFile logDir gt stdout log ReadWriteMode hSetBuffering stdOu
  • XMonad 在不同工作区启动

    我想在 xmonad start 上启动不同工作区中的一些应用程序 这很重要 所以 我写了以下内容startupHook startupApps String startupApps konsole emacs firefox gvim k
  • 机器和管道(或其他类似的库)之间的概念区别是什么?

    我想学习这个概念 以便我能够理解和使用诸如machines http hackage haskell org package machines 我试着跟随R nar Bjarnason 关于机器的演讲 https dl dropbox co
  • 有可能吗?:行为 t [行为 t a] -> 行为 t [a]

    有没有办法有一个Behavior t a 其中 a 在时间 t 的值是 a 中包含的值Behavior t Behavior t a 在时间 t 即 具有以下类型的函数 Behavior t Behavior t a gt Behavior
  • 由于标志字节串 -lt-0_10_4,无法使用 Stack 构建 hello world 程序

    通过生成一个裸露的 hello world 项目 stack new myproject simple 每当我跑步时stack setup stack init or stack build我总是出现以下错误 Downloading lts
  • 如何在 Haskell 中获得列表的中间位置?

    我刚刚开始使用 Haskel 学习函数式编程 我正在慢慢度过Erik Meijer 在 Channel 9 的讲座 http channel9 msdn com shows Going Deep Lecture Series Erik Me
  • 生成所有可能的树

    给定以下数据类型定义 data FormTree Empty Node FormTree FormTree deriving Show 我想编写一个函数 它生成一个无限列表 其中包含按长度排序的所有可能的树 例如节点数量 下面的代码几乎满足
  • 类 GADT 类型变量的未来角色?

    A 昨天的问题 https stackoverflow com q 41135212 3072788有一个定义HList 来自HList https hackage haskell org package HList 0 4 1 0 doc
  • 为什么 Parsec 的 sepBy 停止并且不解析所有元素?

    我正在尝试解析一些逗号分隔的字符串 该字符串可能包含也可能不包含具有图像尺寸的字符串 例如 hello world 300x300 good bye world 我写了下面的小程序 import Text Parsec import qua
  • 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
  • 无点镜头创建不进行类型检查

    在函数中test 我遍历一个列表 从它的成员生成镜头 然后打印一些数据 当我使用有针对性的呼叫风格时 这会起作用 当我使其成为无点时 它无法进行类型检查 为什么会出现这种情况 我该如何解决这个问题 在我看来 GHC 并没有保留排名较高的信息
  • Haskell 下划线与显式变量

    我已经学习 Haskell 几个星期了 我有一个关于下划线的使用的问题 作为函数参数 我认为用一个具体的例子来问我的问题会更好 假设我想定义一个函数 根据提供的索引提取列表的元素 是的 我意识到 已经是预先定义的 我可以定义该函数的两种方法
  • 将 num 的签名键入 double?

    我才刚刚开始为你学习 Haskell 以获得伟大的好处 并且我在类型类方面遇到了一些麻烦 我想创建一个接受任何数字类型并强制其为双精度的函数 我的第一个想法是定义 numToDouble Num gt Double 但我认为这不起作用 因为
  • 以下两个 lambda 函数的空间复杂度

    我正在阅读以下内容 https en wikibooks org wiki Haskell Graph reduction https en wikibooks org wiki Haskell Graph reduction 其内容如下
  • 如何在 Haskell 中安装库?

    我尝试使用控制 Monad Extra andM https hackage haskell org package extra 1 7 10 docs Control Monad Extra html import Control Mon
  • Haskell 中的中缀运算符优先级

    对于以下 Haskell 表达式 返回 a gt gt f 应该读作 返回a gt gt f or 返回 a gt gt f 这里的相关规则是什么 规则始终是函数应用程序的优先级高于任何运算符 因此 return a gt gt f 被解析
  • 如何在 Haskell 中漂亮地打印表格?

    我想在 Haskell 中漂亮地打印一个类似表格的数据结构 列列表 例如 Table StrCol strings a bc c IntCol ints 1 30 2 DblCol doubles 2 0 4 5 3 2 应该渲染类似 st
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频
  • 如何在 Haskell 中制作打勾游戏的图案?

    实现有 2 个参数的函数 ticktick 第一个参数是自然数元组 定义游戏场地的行数和列数 第二个列表包含由玩家 x 和玩家 o 轮流玩的坐标给出的井字游戏比赛的记录 打印游戏的实际状态 其中游戏区域将由字符 和 界定 空方块 以及字符

随机推荐

  • 如何更改 Visual Code Studio 提交作者

    我不知道为什么 但我的 Visual Studio Code 显示错误的提交作者姓名 我正在尝试更改提交的作者 我怎样才能做到这一点 我已经有很多东西了 但没有运气 这是我尝试过的 由于我有三个提交 所以我尝试了git rebase i H
  • 如何排除“git diff-index”中的文件

    我正在使用 git 预提交挂钩来检查提交 预提交脚本基本上做了一件事 exec git diff index check cached HEAD 它还做了一些其他事情 但它们与本次讨论无关 问题是 我的存储库中有各种各样的文件 但并非所有文
  • 通过单击按钮旋转/翻转两种布局

    我有两个布局 xml 文件 我想从一个页面翻转到另一个页面 这两个 xml 文件是 main xml 和 register xml 如果我单击 main xml 中的登录按钮 页面应该翻转并显示 register xml并且在 regist
  • 在 Anaconda 中安装 Kivy

    我正在尝试在 Windows 7 的 Anaconda 3 4 1 1 中安装 Kivy 但我找不到合适的用户指南来指导我如何安装 但到目前为止 我能够在链接上找到在 OS X 上安装它的说明https github com kivy ki
  • matplotlib 中的曲面图

    我有一个 3 元组列表 表示 3D 空间中的一组点 我想绘制一个覆盖所有这些点的曲面 The plot surface函数在mplot3d包要求参数 X Y 和 Z 为二维数组 是plot surface绘制曲面的正确函数以及如何将数据转换
  • 使用 Ruby Date 类处理天文数据

    大约太阳正午 lw 88 743 my longitude jdate Date ordinal to jd Time now year Time now yday n jdate 2451545 0 0009 lw 360 round l
  • 如何在x86汇编编程中表示诸如FFFFFFBB之类的十六进制值?

    我正在学习 x86 内联汇编编程 我想写mov ecx FFFFFFBB 但是编译器无法识别它 像这样的十六进制数字应该如何在内联汇编代码中编写 这取决于您的汇编器的风格 美国电话电报公司 movl 0xFFFFFFBB ecx Intel
  • PyCharm:FooTestCase 不是测试,但 FooTest 是

    如果我打电话给我的测试班FooTestCase我没有看到绿色播放按钮来运行测试 如果我删除 Case 并调用它FooTest出现绿色播放按钮 为什么会发生这种情况 我想要有播放按钮来运行 FooTestCase 的测试 None
  • ANDROID SQLITE 检查表是否有数据

    我想检查一下我的表是否有记录 这是我尝试过的 if cursor null cursor moveToFirst if cursor getInt 0 0 Toast makeText getBaseContext No records y
  • 为什么编译器会生成这个程序集?

    在逐步执行一些 Qt 代码时 我遇到了以下情况 功能QMainWindowLayout invalidate 有以下实现 void QMainWindowLayout invalidate QLayout invalidate minSiz
  • Kendo UI 数据源 - 过滤相关数据

    我在过滤相关数据 多对多 的剑道数据源时遇到问题 我正在使用 ASP NET WebAPI2 和 DataSourceRequest 来捕获服务器上的请求 然后使用 IQueryable 上的 ToDataSourceResult 扩展方法
  • Laravel 4 调用未定义的方法 Illuminate\Database\Eloquent\Collection::links()

    我尝试实现书中的代码 学习 Laravel 4 应用程序开发 http www packtpub com learning laravel 4 application development book 一个简单的使用 CRUD 应用程序如下
  • boost::process::child 关闭输入流后不会退出

    在下面的示例中 我尝试将一些数据写入子进程 该子进程处理数据并将其写入文件 关闭流后 父进程无限期地等待子进程完成 我不知道如何表明我已完成写入数据 并希望子进程停止读取并完成它正在做的任何事情 根据文档调用终止会发送一个SIGKILL h
  • 如果没有 iPad,如何在 iPad 上测试我的网站?

    我收到评论说我的一位网站 tumblr 主题 http www tumblr com theme 11037在 iPad 上崩溃 我没有 iPad 所以我想知道您将如何在 iPad iPhone 或任何其他智能手机上测试您的网站 如果您使用
  • JQuery:帮助使用 .each() 和 .append() 将图片添加到 HTML

    需要修复的简单错误 我不知道出了什么问题 我需要将同一张图片附加到 HTML 中的多个 五个 div 由于某种原因 我的代码将同一张图片附加到每个 div 五次 更清楚地说 五个 div 中的每一个都需要一张图片 现在 这五个人每人都有五张
  • 在另一台计算机上运行 C# 程序时出现 System.IO.FileLoadException

    我目前正在开发一个 C WPF 项目 该项目使用 MySQL Data 和 System Data Sqlite dll 以及其他几个 该项目是一个 Net 4 项目 在我的开发机器上运行没有问题 我创建了一个 MSI 安装程序包 当我添加
  • 对 geom_tile 内的数据进行排序

    我有一个数据框 我想生成一个geom tile 从中绘制 但我希望图表的排序不是基于字母顺序 而是基于该数据框中的变量 structure list V1 c a y w p v h i V2 c r w q m l q g V3 c 5
  • Visual Studio 2010 Express 是否会阻止源代码管理插件?

    我尝试在我的 Visual Studio 2010 Express 上安装此插件 http gitscc codeplex com http gitscc codeplex com 但我在插件存储库中找不到它 插件的 源代码管理 类别是空的
  • 从 PageAsyncTask 调用的方法中,HttpContext.Current 为 null

    我有一个场景 我有一个页面 单击按钮即可打开一个对话框 在单击按钮打开的对话框表单中 我可以从选定的 txt 文件中读取数据列表并构建查询并将数据添加到某些数据库表 由于可能存在大量数据 此过程可能需要很长时间 因此用户在上传完成之前将无法
  • 使用 MonadRef 实现 MonadCont

    有一个众所周知的问题我们不能使用forall类型在Cont返回类型 https stackoverflow com questions 7178919 how to make callcc more dynamic 7180154 7180