跨编译单元的 OCaml 递归模块

2024-03-18

我试图将以下递归模块拆分为单独的编译单元。具体来说,我希望 B 位于它自己的 b.ml 中,以便能够与其他 A 一起重用它。

module type AT = sig
  type b
  type t = Foo of b | Bar
  val f : t -> b list
end

module type BT = sig
  type a
  type t = { aaa: a list; bo: t option }
  val g : t -> t list
end

module rec A : (AT with type b = B.t) = struct
  type b = B.t
  type t = Foo of b | Bar
  let f = function Foo b -> [ b ] | Bar -> []
end
and B : (BT with type a = A.t) = struct
  type a = A.t
  type t = { aaa: a list; bo: t option }
  let g b =
    let ss = List.flatten (List.map A.f b.aaa) in
    match b.bo with
    | Some b' -> b' :: ss
    | None -> ss
end

let a = A.Bar;;
let b = B.({ aaa = [a]; bo = None });;
let c = A.Foo b;;
let d = B.({ aaa = [a;c]; bo = Some b });;

我不知道如何将其划分为不同的单元。

以下句子来自 Xavier Leroy 的paper http://caml.inria.fr/pub/papers/xleroy-recursive_modules-03.pdf关于这个主题给了我希望,可以使用 OCaml 的模块语法进行编码:“该提案不支持编译单元之间的递归。但是,后者可以使用单独编译的函子进行编码,稍后使用模块 rec 获取其固定点构造”。

我已经尝试过 module rec 但似乎找不到一种方法来对其进行类型检查。在 B 的函数 g 中使用 A 的函数 f 似乎会引起麻烦。

(就上下文而言,在原始代码中,A.t是指令类型,B.t是基本块类型。分支指令引用块,块包含指令列表。我想重用基本块类型和相关函数指令集。)


我认为这篇论文指的是这样的事情:

(* a.ml *)

module F (X : sig val x : 'a -> 'a end) =
struct
  let y s = X.x s
end

(* b.ml *)

module F (Y : sig val y : 'a -> 'a end) =
struct
  (* Can use Y.y s instead to get infinite loop. *)
  let x s = Y.y |> ignore; s
end

(* c.ml *)

module rec A' : sig val y : 'a -> 'a end = A.F (B')
       and B' : sig val x : 'a -> 'a end = B.F (A')

let () =
  A'.y "hello" |> print_endline;
  B'.x "world" |> print_endline

运行这个(ocamlc a.ml b.ml c.ml && ./a.out) prints

hello
world

显然,定义A and B我使用的是无意义的,但你应该能够将你自己的定义替换到这个模式中,以及使用命名签名而不是像我一样逐字写出它们。

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

跨编译单元的 OCaml 递归模块 的相关文章

  • 如何覆盖 app/code/core/Mage/Core/functions.php 中的 Magento 函数

    我需要重写此文件中的一个函数 应用程序 代码 核心 Mage Core functions php 问题是 它是如此核心 以至于没有与之关联的类 可能是因为 Core 甚至不是一个模块 有谁知道如何在没有类的情况下覆盖文件中的函数 任何帮助
  • 使用记忆化与不使用记忆化的递归

    我在学校做的作业是用递归计算加泰罗尼亚数 第一个没有记忆 def catalan rec n res 0 if n 0 return 1 else for i in range n res catalan rec i catalan rec
  • Julia:如何让多个工作人员访问模块中的函数?

    我有以下测试模块 MyMod jl 来在 Julia 中存储一些测试函数 一些核心函数是串行编写的 其他函数并行调用核心函数 module MyMod export Dummy distribute data getfrom recombi
  • Python 上的 io.open() 和 os.open() 有什么区别?

    我意识到open 我一直在使用的函数是一个别名io open 以及导入 from os会掩盖这一点 通过以下方式打开文件有什么区别io模块和os module io open 是文件 I O 的首选高级接口 它将操作系统级文件描述符包装在一
  • 最大递归并不完全是 sys.getrecursionlimit() 所声称的。怎么会?

    我制作了一个小函数 可以实际测量最大递归限制 def f x r x try r f x 1 except Exception as e print e finally return r 为了知道会发生什么 我已经检查过 In 28 imp
  • Java hibernate/jpa 如何创建自相关的动态通用实体

    我想使用 JPA hibernate 创建动态和通用的超类 它将针对每个层次结构模型进行扩展 例如 角色 页面 目录 部门 权限 树 我想使用递归和java反射来创建这个对象动态树 它应该看起来像这样 该实体应该引用自身实体 我希望它是完全
  • OCaml 中的线性类型

    Rust http www rust lang org 有一个线性类型系统 有什么 好的 方法可以在 OCaml 中模拟这个吗 例如 当使用 ocaml lua 时 我想确保仅当 Lua 处于特定状态 堆栈顶部的表等 时才调用某些函数 Ed
  • Python:如何导入与子包同名的模块?

    我还没有遇到这个问题 但我很好奇如何导入与子包同名的模块 例如 可能的模块结构可能如下所示 mymodule init py string py 现在 如果我需要mymodule string分包and the string每个 Pytho
  • 计算 python 字典/数组数据结构的非空尾叶 - 递归算法?

    我正在寻找一个函数来查找一种复杂字典 数组结构的所有非空端点 我认为因为我不知道嵌套数组的数量或它们的位置 所以它必须是递归的 而我只是还没有完全理解这种思维方式 所以对于嵌套字典 x top middle nested value nes
  • 生成总和为 N 的所有数字排列

    我正在编写一个程序来创建所有数字 起初 我尝试使用分区函数对数字进行分区 然后对每个数字集进行排列 但是我认为这行不通 最好的方法是递归排列 同时对数字求和 这超出了我的能力范围 抱歉 如果这听起来真的很愚蠢 但我真的不知道 Example
  • 导入 python 模块时如何解决 KeyError?

    我试图从不同的目录级别导入模块 所以我使用了 import os import sys sys path insert 0 os path abspath os path join os path dirname file 但现在我收到这个
  • Intellij 12 - 无法重新导入模块

    所以今天我遇到了一个奇怪的问题 我在 IntelliJ 中的一个模块遇到了一些问题 所以我决定尝试将其清除并从新的结账中重建它 我从 项目 窗口中删除了该模块 然后从我的文件系统中删除 重新下载 我回到 Intellij 并尝试导入该模块
  • Rails - 将模块包含到控制器中,以在视图中使用

    我对 Rails 很陌生 我尝试设置一个要在视图中使用的模块文件 所以我相信正确的行为是将模块定义为控制器中的助手 瞧 它应该可以工作 然而 对我来说情况并非如此 这是结构 lib functions form manager rb 表单管
  • 带子图聚合的递归查询(任意深度)

    我问了一个问题earlier https stackoverflow com questions 28036055 recursive query with sub graph aggreagation关于沿着图表聚合数量 提供的两个答案效
  • Webpack 5 - 资产模块 - 缺少 url-loader 功能 - postTransformPublicPath

    我想按照建议切换到 webpack 5 asset 模块 不幸的是我错过了 webpack url loader 的函数 postTransformPublicPath path any gt any 由于我们应用程序的结构 资产的公共区域
  • 在键盘热插拔上加载模块

    我正在尝试学习如何为 Linux 系统编写模块和驱动程序 类似于this https unix stackexchange com questions 120839 usb kernel module does not load on de
  • 递归和大O

    我最近正在完成一项涉及递归和大 O 表示法的计算机科学作业 我相信我很好地理解了这一点 虽然当然不是完美的 但是有一个问题给我带来了最多的问题 奇怪的是 一看就知道是作业上最简单的一个 使用大哦符号提供最佳增长率来解决以下递归问题 T 1
  • 为什么Python有最大递归深度?

    Python有最大递归深度 但没有最大迭代深度 为什么递归受到限制 把递归当成迭代来对待 而不限制递归调用的次数不是更自然吗 我只想说这个问题的根源来自于尝试实现流 参见这个问题 https stackoverflow com questi
  • 为什么 Haskell 中有协函子和逆变函子的区别,而范畴论却没有区别?

    这个答案是从范畴论的角度来看的 https math stackexchange com a 661989 72174包括以下语句 事实是 协函子和逆变函子之间没有真正的区别 因为每个函子只是一个协变函子 More in details a
  • 如何在 PHP 中递归删除目录及其全部内容(文件+子目录)? [复制]

    这个问题在这里已经有答案了 如何在 PHP 中删除目录及其全部内容 文件和子目录 手册页中的用户贡献部分rmdir http www php net rmdir包含一个不错的实现 function rrmdir dir if is dir

随机推荐