包含仿函数应用程序的子模块

时间:2015-06-21 13:22:16

标签: ocaml

我有这个有子模块的仿函数:

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失败。这很奇怪,因为它看起来像语言语法允许的那样。是否有任何具体理由不允许这样做?

2 个答案:

答案 0 :(得分:2)

足够简单:

module M = F(A)
include M.SubModule

有各种可能的原因,但有一个简单的原因是:如果函数应用程序F(A)的结果未命名,则无法引用它。如果函数在上下文中引入了类型相等性,则会导致问题(特别是错误消息......)

请注意,可以使用类型,模块类型和类类型来执行此操作。 F(M).M.t是一个完全有效的类型表达式。

要完成,在您的情况下,您不需要重新应用仿函数,您已经在之前做过,所以include SubA就足够了。

答案 1 :(得分:2)

模块路径中的OCaml syntax,只允许您引用模块类型,类型构造函数和类型:

  

对于引用类型构造函数,模块类型或类类型,   前缀也可以包含简单的仿函数应用程序(如   语法类扩展 - 模块 - 路径上面)以防定义   模块是仿函数应用程序的结果。

换句话说,要访问实际值,您需要实例化您的模块,然后您可以引用任何值。有关完整示例,请参阅Drup的答案。