【发布时间】:2016-05-25 12:36:10
【问题描述】:
我正在尝试在 ocaml 中构建一系列递归模块。这是一个最简单的例子:
module rec Foo : sig
type t =
| A of int
| B of Foo.t
end = struct
type t =
| A of int
| B of Foo.t
end
module rec Bar : sig
open Foo
type map_t = int -> Foo.t
type t = { foo : map_t }
val bar_of_foo : Foo.t -> t
end = struct
open Foo
let rec bar_of_foo f = match f with
| A a -> let ff (_:int) = a in
{ Bar.foo = ff }
| B b -> { foo = bar_of_foo b.foo }
end
在函数 bar_of_foo 中编译失败,在 A 的匹配中,与 Error: unbound type constructor f。
我不明白为什么会这样 - 字段 foo 被定义为具有类型 map_t = int -> Foo.t,而 f 具有签名 int -> Foo.t。
我还尝试将记录字段 foo 简单地称为 foo 而不是 Bar.foo(在 B 的匹配案例中 - 这给了我一个 Errror: unbound record field foo 错误)。
感激地收到任何指示或建议。
史蒂夫
【问题讨论】:
-
(1) 最里面的
f(最外面的f是bar_of_foo的参数)具有签名int -> int,因为它使用a : int作为其返回值。我认为删除名称冲突是个好主意。 (2) 我看不到Foo和Bar之间的递归依赖关系。我只是看到Bar使用Foo,但不是相反。 -
谢谢安东。在帖子中删除了名称冲突。
-
好的,所以我不明白
bar_of_foo中的打字是如何解决的。第一行:` | A a -> let ff (_:int) = a in { Bar.foo = ff }` 从匹配A( =Foo.A) 类型开始。而且,Foo.A的类型是int。所以我明白为什么ff的签名是int -> int。但是A是Foo.t的变种之一,那为什么bar_of_foo可以没有签名Foo.t -> int呢?
标签: ocaml