我有这个有子模块的仿函数:
module type PT = sig
type t
val to_string: t -> string
end
module A(P:PT) = struct
module SubA = struct
type t = T of P.t | F of float
end
end
我想用include来扩展它。这甚至有效:
module Aplus(P:PT) = struct
include A(P)
let print x = print_string (P.to_string x)
end
但由于某种原因,它不适用于子模块。
module Aplus(P:PT) = struct
include A(P)
let print x = print_string (P.to_string x)
module SubAplus = struct
include A(P).SubA (* Syntax error here *)
end
end
在仿函数应用程序之后,子模块引用上的Syntax error
失败。这很奇怪,因为它看起来像语言语法允许的那样。是否有任何具体理由不允许这样做?
答案 0 :(得分:2)
足够简单:
module M = F(A)
include M.SubModule
有各种可能的原因,但有一个简单的原因是:如果函数应用程序F(A)
的结果未命名,则无法引用它。如果函数在上下文中引入了类型相等性,则会导致问题(特别是错误消息......)
请注意,可以使用类型,模块类型和类类型来执行此操作。 F(M).M.t
是一个完全有效的类型表达式。
要完成,在您的情况下,您不需要重新应用仿函数,您已经在之前做过,所以include SubA
就足够了。
答案 1 :(得分:2)
模块路径中的OCaml syntax,只允许您引用模块类型,类型构造函数和类型:
对于引用类型构造函数,模块类型或类类型, 前缀也可以包含简单的仿函数应用程序(如 语法类扩展 - 模块 - 路径上面)以防定义 模块是仿函数应用程序的结果。
换句话说,要访问实际值,您需要实例化您的模块,然后您可以引用任何值。有关完整示例,请参阅Drup的答案。