Ocaml: constructor type transfer between modules

I have this type of module:

module type MOD = sig type operand type op val print : op -> string end;; 

Implementation MOD:

 module M1:MOD = struct type operand = Mem of int | Reg of int | Const of int type op = Add of operand * operand| Sub of operand * operand let print op = match op with | Add _ -> "Add" | Sub _ -> "Sub" end;; 

I want to create a parameterized module to take the type op from the first module and implement a function for variables of this type. eg:

 module ARCHI = functor (M : MOD) -> struct type op = M.op let execute o = match o with | Add (x,y) -> x + y | Sub (x,y) -> x - y end;; 

I get the error : Unbound constructor Add . How can i do this?

+4
source share
2 answers

You declared the type op abstract in MOD, and then you defined your functor to take a module M of type MOD. Thus, you correctly cannot have access to the op implementation. Otherwise, your functor will not do what he claims, which accepts any module of type MOD, and not just the specific M1 that you defined.

You can expose the op implementation in MOD by writing the full type definition in the signature. However, it is unclear if you really need a functor.

+7
source

There ARCHI no Add declaration in ARCHI . The Add M constructor must be written M.Add . In addition, as Ashish Agarwal already noted, the ARCHI module may accept an argument that does not have an Add constructor, since the MOD signature does not mention a constructor named Add .

If you want to use Add in M , you must declare it when you declare M , i.e. in an argument to the constructor. One way to do this is to completely specify the type op in the MOD signature:

 module type MOD = sig type operand type op = Add of operand * operand| Sub of operand * operand val print : op -> string end;; 

If you use the MOD signature for other purposes, where the type op must remain abstract, there is a notation for adding type equivalents to the signature. With the original definition of MOD you can write

 module type MOD_like_M1 = MOD with type op = Add of operand * operand| Sub of operand * operand module ARCHI = functor (M : MOD_like_M1) -> … 

or

 module type MOD_like_M1 = MOD with type op = M1.op module ARCHI = functor (M : MOD_like_M1) -> … 

or

 module type MOD_like_M1 = MOD with type op = Add of operand * operand| Sub of operand * operand module ARCHI = functor (M : MOD with type op = M1.op) -> … 

In any case, in the definition of ARCHI you need to open M or write M.Add .

+2
source

Source: https://habr.com/ru/post/1389287/


All Articles