我正在尝试使用相互递归模块定义一个变量,假设一个 Todo 可以有很多 Note 并且 Note 可以属于一个 Todo:
module Sig = {
module type NoteSig = {type t;};
module type TodoSig = {type t;};
};
/* same file */
module Same = {
module rec Note: Sig.NoteSig = {
type t = {todo: Todo.t};
}
and Todo: Sig.TodoSig = {
type t = {
text: string,
notes: array(Note.t),
};
};
};
/* different files */
module A = {
module Note = (T: Sig.TodoSig) => {
type t = {todo: T.t};
};
};
module B = {
module Todo = (N: Sig.NoteSig) => {
type t = {notes: array(N.t)};
};
};
module C = {
module rec NoteImpl: Sig.NoteSig = A.Note(TodoImpl)
and TodoImpl: Sig.TodoSig = B.Todo(NoteImpl);
};
/* impl */
let todo1: Same.Todo.t = {notes: [||]};
let todo2: C.TodoImpl.t = {notes: [||]};
let todo3 = Same.Todo.{notes: [||]};
let todo4 = C.TodoImpl.{notes: [||]};
Js.log2(todo1, todo2);
但是我不能用这种类型定义一个变量,编译器告诉我:
36 │
37 │ /* impl */
38 │ let todo1: Same.Todo.t = {notes: [||]};
39 │ let todo2: C.TodoImpl.t = {notes: [||]};
40 │
The record field notes can't be found.
If it's defined in another module or file, bring it into scope by:
- Annotating it with said module name: let baby = {MyModule.age: 3}
- Or specifying its type: let baby: MyModule.person = {age: 3}
如果有帮助,请使用 Ocaml 中的相同代码:
module Sig =
struct
module type NoteSig = sig type t end
module type TodoSig = sig type t end
end
module Same =
struct
module rec Note:Sig.NoteSig = struct type t = {
todo: Todo.t;} end
and Todo:Sig.TodoSig =
struct type t = {
text: string;
notes: Note.t array;} end
end
module A =
struct module Note(T:Sig.TodoSig) = struct type t = {
todo: T.t;} end end
module B =
struct
module Todo(N:Sig.NoteSig) = struct type t = {
notes: N.t array;} end
end
module C =
struct
module rec NoteImpl:Sig.NoteSig = A.Note(TodoImpl)
and TodoImpl:Sig.TodoSig = B.Todo(NoteImpl)
end
let todo1: Same.Todo.t = { notes = [||] }
let todo2: C.TodoImpl.t = { notes = [||] }
let todo3 = let open Same.Todo in { notes = [||] }
let todo4 = let open C.TodoImpl in { notes = [||] }
let _ = Js.log2 todo1 todo2
抱歉,代码太长,请丢弃下面的这些行。