gpt4 book ai didi

types - 跨越 "module type ="的 OCaml 递归类型

转载 作者:行者123 更新时间:2023-12-04 00:30:13 25 4
gpt4 key购买 nike

我有一组复杂的约束(主要是教学),导致我想做这样的事情:

type alpha = ... ENV.env ...
and module type ENV = sig
type env
val foo : ...alpha...
end

但这不是合法的 OCaml。一方面,您不能拥有 module type ENV =作为递归类型定义的一部分。 (我认为甚至没有任何版本的递归声明仅限于模块类型声明。)对于两个,你不能有 ENV.env调用模块类型的组件;你只能写 M.env在哪里 M是一个实现的模块结构。但是,如果像上面这样的事情是合法的,它就会捕捉到我的目标。

这是一个简化的测试用例,展示了我的一些限制。
(* M1 is really the contents of an .mli file, not a module *)
module M1 = struct
type env (* I want env to be opaque or abstract at this point ... *)
type alpha = A of int | B of env * int
type beta = C of int | D of alpha
module type ENV = sig
type env (* ...but to be unified with this env *)
val foo : unit -> beta -> unit
val empty : env
end
end

(* M2 needs to be in another_file.ml *)
module M2 = struct
(* here we provide an implementation of M1.ENV *)
module E1 : M1.ENV = struct
type env = char
let foo () _ = ()
let empty = 'X'
end

(* then I'd want this to typecheck, but it doesn't *)
let _ = M1.B(E1.empty, 0)
end

M1ENV 声明前的部分需要引用 env类型,然后是 ENV 的声明本身需要引用 M1其他部分发生的一些事情.所以不清楚哪个应该先来。如果 ENV无需引用 beta ,它又指 alpha , 我可以把 ENV在文件的开头和 include ENV (正如我上面所说,这实际上是一个 .mli 文件)以便访问 env alpha 的声明类型.我不确定这是否真的会导致 envalphaenv 相同在 M1.ENV (在 OCaml include 中,模块类型被称为只是其内容的文本副本);但无论如何,由于相互依赖,我不能在这里做。所以我必须预先声明 type envM1 的开头.我们不在 M1 中,这对我的需求很重要。指定 env 的实现.

我在上面为 M1 给出的声明被 OCaml 接受,但两种类型 env不统一。这并不奇怪,但我的任务是找到一些能够统一它们的扭曲。当我们为 ENV 提供实现时稍后,如 M2上面,我们希望能够使用它来提供 M1.alpha 的实例.但目前我们不是: M1.B(E1.empty, 0)不会进行类型检查。

现在有一个解决方案。我可以有 M1.alpha使用类型变量 'env而不是抽象类型 env .但是后来 M1.alpha需要在 'env 上进行参数化, 然后 M1.beta是的,并且由于我的类型相互依赖,整个项目中的几乎每个类型都需要在 'env 上进行参数化。 type,一个具体的实例,直到我们到达 module M2 才能提供。 ,在构建链的更下方。这在教学上是不可取的,因为它使所有类型都更难理解,即使在环境没有直接相关性的情况下也是如此。

所以我一直在试图弄清楚我是否可以使用仿函数或一流的模块执行一些技巧,使我能够获得我在 module M1 中寻找的那种相互依赖关系。 ,并提供 env 的实现输入后面的文件,这里用 module M2 表示.我还没有弄清楚这样的事情。

最佳答案

我不知道这是否有帮助,但这个小例子对我有用:

# module rec A : sig
type alpha = B.env list
end = A
and B : sig
type env
val foo: A.alpha
end = struct
type env = int
let foo = [3]
end;;
module rec A : sig type alpha = B.env list end
and B : sig type env val foo : A.alpha end
# B.foo
- : A.alpha = [<abstr>]
它似乎有一个让人想起你最初的例子的结构,限制是 alpha最终包裹在一个模块中。

关于types - 跨越 "module type ="的 OCaml 递归类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29115356/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com