Ocaml:在模块之间传递构造函数类型

时间:2012-01-04 14:53:59

标签: types module ocaml abstract

我有这个模块类型:

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

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

我想创建一个参数化模块,从第一个模块中取op类型 并对该类型的变量实现函数。像这样:

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

我收到错误: Unbound constructor Add。我该如何管理?

2 个答案:

答案 0 :(得分:7)

您已在MOD中声明类型op是抽象的,然后您已定义您的仿函数以获取MOD类型的模块M.因此,您正确无法访问op的实现。否则,您的仿函数不会执行它所声称的任何 MOD类型的模块,而不仅仅是您定义的特定M1。

您可以通过在签名中写出类型的完整定义来公开MOD中的op实现。但是,目前还不清楚你真的需要一个仿函数。

答案 1 :(得分:2)

Add中没有ARCHI声明。 Add的{​​{1}}构造函数必须写为M。此外,由于已经noted by Ashish AgarwalM.Add模块可以采用不具有ARCHI构造函数的参数,因为签名Add未提及任何名为{{的构造函数1}}。

如果要在MOD中使用Add,则必须在声明Add时声明它,即在构造函数的参数中声明它。一种方法是在签名M中完全指定类型M

op

如果您将签名MOD用于module type MOD = sig type operand type op = Add of operand * operand| Sub of operand * operand val print : op -> string end;; 类型必须保持抽象的其他用途,则有一种用于向签名添加类型等值的表示法。使用MOD的原始定义,您可以编写

op

MOD

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

无论如何,在module type MOD_like_M1 = MOD with type op = M1.op module ARCHI = functor (M : MOD_like_M1) -> … 的定义中,您需要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) -> … 或撰写ARCHI