4

Let's say that I have a 1 -> n relation: one todo can has many (or zero) notes and a note can have zero or one todo. How can I achieve this relation in ReasonML? (binding for an external lib)

Here is what I have come with at the moment (which is of course not working)

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");

What if Note and Todo are in one file, an are in separated files?

Quang Linh Le
  • 751
  • 1
  • 7
  • 16

1 Answers1

5

I am not familliar with Reason but in OCaml, one would do this kind of stuff using mutually recursive module, as in the following minimal example.

Using mutally recursive requires to defines their module type:

module type NoteSig = sig
  type t
end

module type TodoSig = sig
  type t
end

and the actual modules:

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

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

If you prefer both module to be in a separate file, you can do pretty much the same thing using functors (still using the module signatures, let's say in a file sig.ml):

a.ml:

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

b.ml:

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

You can now instanciate your modules in an other file :

c.ml:

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

I can only suppose there is a way to to do the same thing in Reason, probably by adding a lot of brackets everywhere. Hope it helps.

ghilesZ
  • 1,502
  • 1
  • 18
  • 30
  • Thank you for your reply @ghilesZ. I tried your solution and it compiled fine but I cannot create an instance of Todo, please let me know what I did wrong https://gist.github.com/linktohack/7eb131c52f35af4e9429d7b3d17a59c3 – Quang Linh Le Jul 04 '18 at 14:32
  • Oh this is a different question. Here i think that you cant access the field "note" becose it does not appear in your signature. You can either make it appear in it, or add constructors/accessors to your module that allow you to manipulate your data without knowing your implementation. Anyway you should consider accepting the answer if it fixed your original problem. – ghilesZ Jul 04 '18 at 15:11