为什么不可能将仿函数参数模块中的模块类型包含到仿函数结果模块中的模块类型中?
Why is it impossible to include module type from functor parameter module into module type in resulting module of functor?
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
不是抽象的。需要提供a
才能申请S_FROM_CONTAINER
.
(*
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
IMPL_CONTAINER_S
中的模块也不是抽象模块类型:
(* 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
^^^^^^^^^^^
Error: This module type is not a signature
为什么我不能这样做?对我来说,它看起来像一些差距,不仅在编译器上而且在语言概念上也是如此。我想了解什么?
简而言之,include
不是模块类型系统的一部分,它们通过内联签名的内容来处理签名。在模块系统中添加 include
表达式并不是那么简单,因为不能在任何上下文中包含任何模块类型。考虑例如:
module F(X:sig module type x module type y end) = struct
module type result = sig
include x
include y
end
end
并不总是有效。考虑例如,
module type x = sig
type t
val x: t
end
module type y = sig
type t
val y: t
end
然后
module type t = sig
include x
include y
end
产生错误
Error: Illegal shadowing of included type t/863 by t/865
Line 2, characters 2-11:
Type t/863 came from this include
Line 3, characters 2-10:
The value x has no valid type if t/863 is shadowed
因此 include s
并不总是有效的,要使包含抽象类型模块成为可能,需要改进模块类型系统以捕获这种情况。
此外,拥有动态数量的运行时组件的模块类型将需要不同的编译方案,因为查询模块内的路径不能再简化为查询块中的 statistically-known 索引。
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
不是抽象的。需要提供a
才能申请S_FROM_CONTAINER
.
(*
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
IMPL_CONTAINER_S
中的模块也不是抽象模块类型:
(* 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
^^^^^^^^^^^
Error: This module type is not a signature
为什么我不能这样做?对我来说,它看起来像一些差距,不仅在编译器上而且在语言概念上也是如此。我想了解什么?
简而言之,include
不是模块类型系统的一部分,它们通过内联签名的内容来处理签名。在模块系统中添加 include
表达式并不是那么简单,因为不能在任何上下文中包含任何模块类型。考虑例如:
module F(X:sig module type x module type y end) = struct
module type result = sig
include x
include y
end
end
并不总是有效。考虑例如,
module type x = sig
type t
val x: t
end
module type y = sig
type t
val y: t
end
然后
module type t = sig
include x
include y
end
产生错误
Error: Illegal shadowing of included type t/863 by t/865 Line 2, characters 2-11: Type t/863 came from this include Line 3, characters 2-10: The value x has no valid type if t/863 is shadowed
因此 include s
并不总是有效的,要使包含抽象类型模块成为可能,需要改进模块类型系统以捕获这种情况。
此外,拥有动态数量的运行时组件的模块类型将需要不同的编译方案,因为查询模块内的路径不能再简化为查询块中的 statistically-known 索引。