【发布时间】:2020-12-27 08:28:08
【问题描述】:
OCaml 不提供直接通过仿函数创建模块类型的能力。但是,它允许对嵌套模块类型进行一些操作。所以,我可以使用参数中的模块类型来绑定结果中的模块类型:
module CONTAINER = struct
module type S = sig
val a : int
end
end
module COPY (CONTAINER : sig module type S end) = struct
module type S = CONTAINER.S
end
module type S_FROM_CONTAINER = COPY(CONTAINER).S
S_FROM_CONTAINER 不是抽象的。申请S_FROM_CONTAINER需要提供a。
(*
module Impl : S_FROM_CONTAINER = struct
end
> Error: Signature mismatch:
> Modules do not match: sig end is not included in S_FROM_CONTAINER
> The value `a' is required but not provided
*)
module Impl : S_FROM_CONTAINER = struct
let a = 42
end
另外,我可以使用来自CONTAINER 的S 作为生成模块中模块类型中的一种模块:
module AS_TYPE_OF_IMPL (CONTAINER : sig module type S end) = struct
module type S = sig
module Impl : CONTAINER.S
end
end
module type IMPL_CONTAINER_S =
AS_TYPE_OF_IMPL(CONTAINER).S
IMPL_CONTAINER_S 中的Impl 模块也不是抽象模块类型:
(* module ImplContainer : IMPL_CONTAINER_S = struct
module Impl = struct end
end
> Error: Signature mismatch:
> Modules do not match:
> sig module Impl : sig end end
> is not included in
> IMPL_CONTAINER_S
> In module Impl:
> Modules do not match: sig end is not included in CONTAINER.S
> In module Impl:
> The value `a' is required but not provided
*)
module ImplContainer : IMPL_CONTAINER_S = struct
module Impl = struct let a = 42 end
end
没关系。我认为这是一个强大的工具。但我发现了一个让我难过的局限。不可能将此模块类型包含到另一个模块类型中。
module EXTEND_S (CONTAINER : sig module type S end) = struct
module type S = sig
include CONTAINER.S
val extention : int
end
end
或者
module AS_PART_OF_IMPL (CONTAINER : sig module type S end) = struct
module type S = sig
module Impl : sig
include CONTAINER.S
val extention : int
end
end
end
include CONTAINER.S^^^^^^^^^^^
错误:此模块类型不是签名
为什么我不能这样做?对我来说,这看起来像是一些差距,不仅在编译器上,而且在语言概念上也是如此。我想了解什么?
【问题讨论】: