首页 > 解决方案 > 循环依赖reasonml

问题描述

假设我有一个1 -> n关系:一个待办事项可以有许多(或零个)笔记,而一个笔记可以有零个或一个待办事项。如何在 ReasonML 中实现这种关系?(绑定外部库)

这是我目前所带来的(当然是行不通的)

module Note = {
  module Attributes = {
    [@bs.deriving abstract]
    type t = {
      [@bs.optional]
      id: float,
      [@bs.optional]
      text: string,
      [@bs.optional]
      todo: Todo.Attributes.t,
    };
  };
};

module Todo = {
  [@bs.deriving abstract]
  type t = {
    [@bs.optional]
    id: float,
    [@bs.optional]
    title: string,
    [@bs.optional]
    completed: bool,
    [@bs.optional]
    notes: array(Note.Attributes.t),
  };
};

let todo = Todo.Attribute.t(~title="hello");

如果 Note 和 Todo 在一个文件中,一个在不同的文件中怎么办?

标签: ocamlreasonbucklescript

解决方案


我不熟悉 Reason,但在 OCaml 中,人们会使用相互递归模块来做这种事情,如下面的最小示例所示。

使用相互递归需要定义它们的模块类型:

module type NoteSig = sig
  type t
end

module type TodoSig = sig
  type t
end

和实际的模块:

module rec Note : NoteSig = struct
  type t = {
      todo: Todo.t
    }
end

and Todo : TodoSig = struct
  type t = {
      notes: Note.t array
  }
end

如果您希望两个模块都在一个单独的文件中,您可以使用仿函数做几乎相同的事情(仍然使用模块签名,让我们在文件sig.ml中说):

毫升:

module Note (T:Sig.TodoSig) = struct
  type t = {
     todo: T.t
  }
end

毫升:

module Todo (N:Sig.NoteSig) = struct
  type t = {
    notes: N.t array
  }
end

您现在可以在另一个文件中实例化您的模块:

毫升:

module rec NoteImpl = (A.Note(TodoImpl):NoteSig)
and TodoImpl = (B.Todo(NoteImpl):TodoSig)

我只能假设有一种方法可以在 Reason 中做同样的事情,可能是在各处添加很多括号。希望能帮助到你。


推荐阅读