我有这个模块类型:
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
。我该如何管理?
答案 0 :(得分:7)
您已在MOD中声明类型op
是抽象的,然后您已定义您的仿函数以获取MOD类型的模块M.因此,您正确无法访问op的实现。否则,您的仿函数不会执行它所声称的任何 MOD类型的模块,而不仅仅是您定义的特定M1。
您可以通过在签名中写出类型的完整定义来公开MOD中的op实现。但是,目前还不清楚你真的需要一个仿函数。
答案 1 :(得分:2)
Add
中没有ARCHI
声明。 Add
的{{1}}构造函数必须写为M
。此外,由于已经noted by Ashish Agarwal,M.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
。