延续 monad 中的 StackOverflow

2023-11-27

使用以下延续单子:

type ContinuationMonad() =
    member this.Bind (m, f) = fun c -> m (fun a -> f a c)
    member this.Return x = fun k -> k x

let cont = ContinuationMonad()

我不明白为什么以下会给我一个堆栈溢出:

let map f xs =
    let rec map xs =
        cont {
            match xs with
            | [] -> return []
            | x :: xs ->
                let! xs = map xs
                return f x :: xs
        }
    map xs id;;

let q = [1..100000] |> map ((+) 1)

而以下情况则不然:

let map f xs =
    let rec map xs =
        cont {
            match xs with
            | [] -> return []
            | x :: xs ->
                let! v = fun g -> g(f x)
                let! xs = map xs
                return v :: xs
        }
    map xs id;;

let q = [1..100000] |> map ((+) 1)

要修复您的示例,请将此方法添加到 monad 的定义中:

member this.Delay(mk) = fun c -> mk () c

显然,溢出的部分是递归调用中对大输入列表的破坏map。拖延一下就能解决问题。

请注意,您的第二个版本将递归调用map在另一个后面let!脱糖到Bind和一个额外的 lambda,实际上延迟了递归调用map.

在得出这个结论之前,我不得不追寻一些错误的线索。有帮助的是观察到StackOverflow被抛出OCaml以及(尽管在更高的N)除非递归调用被延迟。尽管F#TCO 有一些怪癖,OCaml已经得到更多证实,所以这让我确信问题确实出在代码而不是编译器上:

let cReturn x = fun k -> k x
let cBind m f = fun c -> m (fun a -> f a c)

let map f xs =
  (* inner map loop overflows trying to pattern-match long lists *)
  let rec map xs =
    match xs with
      | [] -> cReturn []
      | x :: xs ->
        cBind (map xs) (fun xs -> cReturn (f x :: xs)) in
  map xs (fun x -> x)

let map_fixed f xs =
  (* works without overflowing by delaying the recursive call *)
  let rec map xs =
    match xs with
      | [] -> cReturn []
      | x :: xs ->
        cBind (fun c -> map xs c) (fun xs -> cReturn (f x :: xs)) in
  map xs (fun x -> x)

let map_fused f xs =
  (* manually fused version avoids the problem by tail-calling `map` *)
  let rec map xs k =
    match xs with
      | [] -> k []
      | x :: xs ->
        map xs (fun xs -> k (f x :: xs)) in
  map xs (fun x -> x)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

延续 monad 中的 StackOverflow 的相关文章

  • F# 中的动态编程

    实现解决问题的动态规划算法的最优雅的方法是什么子问题重叠的问题 http en wikipedia org wiki Overlapping subproblem 在命令式编程中 人们通常会创建一个按问题大小索引的数组 至少在一维 然后算法
  • 如何让 do 块提前返回?

    我正在尝试使用 Haskell 抓取网页并将结果编译到一个对象中 如果出于某种原因 我无法从页面获取所有项目 我想停止尝试处理页面并提前返回 例如 scrapePage String gt IO scrapePage url do doc
  • F# 匹配 ->

    我想做类似的东西 Nemerle 语法 def something match STT 1 with st Summ 2 with st AVG gt st summbycol counter STT 在 F 上 那么 F 是真的吗 没有对
  • obj[] 和 string[] 作为参数

    我在用Microsoft FSharp Reflection FSharpValue MakeUnion这需要一个Reflection UnionCaseInfo and an obj 可以为空 作为参数 但是 我得到了Type misma
  • 基于函数签名的模式匹配

    在 F 中 您可以对函数签名进行模式匹配 我想用一个函数来装饰多个函数 该函数测量函数的执行情况并调用 statsd 我当前的功能是 let WrapFunctionWithPrefix metrics Metric Client IRec
  • 如何从 C# 调用 F# 类型扩展(静态成员函数)

    FSharp 代码的结构如下 我无法控制源代码 namespace FS
  • 在构建过程中引用自身内部的记录

    我正在尝试创建一条记录 该记录在同一构造函数中使用先前定义的字段之一来计算另一个字段的值 例如 myRecordType Foo int Bar int myRecord Foo 5 Bar Array init Foo fun i gt
  • 在类型扩展中重载运算符

    好的 所以我基本上尝试将绑定运算符添加到选项类型中 似乎我尝试的所有内容都有一些不明显的警告阻止我这样做 我怀疑这与 NET 类型系统的限制有关 并且可能与类型类无法在用户代码中实现的原因相同 不管怎样 我已经尝试了一些事情 首先 我尝试了
  • 如何在 F# 中定义这种惰性(无限?)数据结构

    我在定义以下简单文本光标时遇到问题 该光标由元组表示 其中第一个元素是当前字符 如果函数获取下一个元素或崩溃 则第二个元素是 let rec nextAt index text if index lt String length text
  • 您将如何在 F# 中解决这个问题? (高频传感器数据)

    我是一名机械工程研究生 我的导师刚刚要求我为我们的一个传感器项目编写一个数据可视化实用程序 由于现在是夏天 他希望我能从中获得一些乐趣 我认为这将是学习一门擅长科学计算的语言的好时机 所以我直接开始学习 F 由于我是函数式编程范例的新手 因
  • F# 内联如何工作?

    对于 F 我的理解是您可以使用 inline 关键字在调用站点执行类型专门化 那是 val inline a gt b gt c when a or b static member a b gt c 约束条件是 a or b必须有一个静态成
  • F#:模式构成?

    我正在尝试编写一个由另外两个模式组成的模式 但我不确定如何去做 我的输入是字符串列表 文档 我有一个与文档标题匹配的模式和一个与文档正文匹配的模式 该模式应该匹配整个文档并返回标题和正文模式的结果 您可以使用以下命令一起运行两个模式 您在问
  • 何时使用接口,何时使用高阶函数?

    给定一个具有以下层的 ASP NET MVC 应用程序 UI 视图 CSS Javascript 等 控制器 服务 包含业务逻辑和数据访问 没有单独的数据访问层的原因是我正在使用 SQL 类型提供程序 以下代码可能不起作用 因为它只是原始草
  • 是否可以使用 fparsec 解析“越位”(基于缩进)语言?

    我希望将 FParsec 用于基于缩进的类似 python 的语言 我知道这必须在词法分析阶段完成 但 FParsec 没有词法分析阶段 是否可以使用 FParsec 或者 词法分析后如何提供它 P D 我是 F 新手 但在其他语言方面经验
  • 我可以提供类型作为 F# 中类型提供程序的输入吗?

    这样做有什么我应该注意的陷阱吗 您知道处理我可能遇到的相同 pb 的现有代码吗 Thks 不幸的是 您无法将类型作为静态参数传递给类型提供程序 使用传递的静态参数MyProvider lt first argument 42 gt 必须是原
  • 使用异步工作流程并行化的最佳实践

    假设我想抓取一个网页并提取一些数据 我很可能会写这样的东西 let getAllHyperlinks url string async let req WebRequest Create url let rsp req GetRespons
  • F# - 构造嵌套类型

    我想这是非常基本的 F 问题 类型有 type Id1 Id1 of int type Id2 Id2 of string type Id Id1 Id2 type Child Id Id Smth string list type Nod
  • Visual Studio 2019 F# NU1101 无法找到包 FSharp.core

    我刚刚开始使用 Microsoft Visual Studio 和 F 我已尽可能地遵循他们的教程 但是当我尝试运行代码时 他们告诉我收到错误 NU1101 Unable to find package FSharp Core No pac
  • F# 开发和单元测试? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我刚刚开始使用 F 这是我的第一种函数式语言 我一直在准专门使用 C 工作 并且非常喜欢 F 引导我重新思考如何编写代码 我觉得有点迷失方向的一
  • 如何在使用 F# FsYacc 解析期间添加和使用自定义上下文参数?

    我在用着FsLex and FsYacc用于 F 应用程序中的字符串解析 在抽象语法树 AST 创建期间 解析器必须决定如何创建 AST 创建不同的树 抛出异常等 解析器的行为必须取决于几个参数 Here http fsharppowerp

随机推荐

  • 将脚本插入多个 Google 电子表格

    我是一名业余程序员 我实际上只做了一些事情来让我的生活更轻松 我设置了 Google 表单和电子表格来跟踪学校不同年级的纪律问题 我编写了一个简短的脚本 通过电子邮件通知适当的人员任何提交 并且可以过滤和创建有关选定学习者的报告 因为我做D
  • 使用 Perl 查找文件

    File Find and the wanted 子程序 这个问题比原来的标题 子例程的原型和前向声明 要简单得多 我希望答案 无论多么简单 都能帮助我理解子例程 函数 原型和范围以及File Find module 使用 Perl 子例程
  • Python 将元组转换为整数

    有没有可以将元组转换为整数的函数 Example input 1 3 7 output 137 gt gt gt reduce lambda rst d rst 10 d 1 2 3 123
  • CS8019 临时文件 MSBuild 服务器上的 Assemblyinfo 错误

    我的构建服务器上出现代码分析错误 错误是 NETFramework 版本 v4 6 AssemblyAttributes cs 3 1 错误CS8019 不必要的using指令 它位于 Visual Studio 创建的临时文件中 在我的项
  • Send() 之后的 UdpClient、Receive() 不起作用?

    考虑以下代码 client Send data data Length endpoint byte response client Receive ref endpoint 然而 根据 WireShark 网络嗅探器 的说法 远程主机确实会
  • 键盘显示元素的位置混乱

    我有需要手机触摸键盘输入的游戏 它的显示有问题 每当键盘出现在文本输入焦点时 我的所有位置 绝对的元素都会变得混乱 是否有一个插件可以使移动键盘始终显示 以便我重新定位所有元素 或者我需要更改 css 来制作元素 以便键盘显示时不会混乱 我
  • 直接连接到 SQL Azure 时的登录前握手问题

    目前 我们的开发环境中遇到了一个相当麻烦的问题 并显示以下消息 A connection was successfully established with the server but then an error occurred dur
  • 使用 java 处理 Postgresql 事务

    我有两个带有preparedStatement 的查询块 这是第一个 String sql update cikan malzeme set miktar where proje id and malzeme id PreparedStat
  • 支持转储和加载的纯 Javascript YAML 库? [复制]

    这个问题在这里已经有答案了 这样的事情存在吗YAML aka YAML 如果这个曾经存在过 那么它一定已经被抹去了 因为最新的搜索结果一无所获 看起来有很多实现dump仅从 Javascript 到 YAML 输出 但很难找到支持转储和加载
  • serviceAccountKey 在哪里或者是什么。json 是 firebase 实时数据库的 Node js 示例

    我已经下载了 zipFirebase real time database node js sample并导航到数据库部分 https github com firebase quickstart nodejs tree master da
  • 如何从 URL 字符串中获取参数?

    我有一个 HTML 表单字段 POST url 有一些 URL 字符串作为值 示例值是 https example com test email protected https example com test email protecte
  • 在原始返回类型函数上返回“null”?

    我有一个函数返回一个int给定键的值 来自HashMap
  • 查找nohup命令运行的进程

    我使用以下命令在 Centos 中运行服务器可执行文件 nohup server 现在我需要终止该进程 server 但我尝试过 ps a 命令来获取PID但我无法获得该过程 知道如何杀死 server now ps auxwww grep
  • “R 无法解析为变量”? [复制]

    这个问题在这里已经有答案了 在 Eclipse 中 我从源创建了一个项目 现在它显示错误 R 无法解析为变量 从我在这里发现的情况来看 我已经清除并重建了项目 但 R 文件仍然没有出现在 gen 文件夹中 有任何想法吗 不用担心 首先 您可
  • Pandas - 按连续范围分组

    我有一个具有以下结构的数据框 开始 结束和高度 数据框的一些属性 数据帧中的一行始终从上一行结束的位置开始 即如果第 n 行的结尾是 100 则第 n 1 行的开头是 101 第 n 1 行的高度始终与第 n 1 行的高度不同 这就是数据位
  • Ruby File.open 模式和选项是什么?

    Ruby s File open将模式和选项作为参数 在哪里可以找到模式和选项的完整列表 In Ruby IO 模块文档 我想 Mode Meaning r Read only starts at beginning of file def
  • CSS 定位 - 两个相邻的元素

    好吧 我知道这个问题已经出现了至少数百次 但这个定位让我发疯 有人可以帮助我吗 我有一个带有表格和 div 标签的 portlet 页面 基本上是 html 我想将它们放置在彼此旁边 表格在左侧 div 在右侧 以下是我的 html 的部分
  • 如何将文本文件与我的类库一起包含在 Visual Studio 2017 为我创建的 NuGet 包中?

    我的文本文件位于我的类库项目中 我将其 构建操作 设置为 内容 并将 复制到输出目录 设置为 如果较新则复制 因此 csproj 有一个类似以下的部分
  • 更改另一个 PFuser 对象中的数据

    在我的游戏中 一个用户可以对另一个用户造成伤害 并拿走他们的一些金币 gold 变量存储在其他用户的 PFUser 对象中 一个用户如何更改存储在其他用户 PFUser 对象中的黄金值 您无法保存或删除未经身份验证的 PFUser 实现该功
  • 延续 monad 中的 StackOverflow

    使用以下延续单子 type ContinuationMonad member this Bind m f fun c gt m fun a gt f a c member this Return x fun k gt k x let con