Ocaml 为什么在一级模块包装中禁用破坏性替换?
假设:Ocaml 为什么在一级模块包装中禁用破坏性替换?,ocaml,Ocaml,假设: module type Foo = sig type t val foo : t -> t end module M = struct type t = int let foo t = t + 1 end 那么我会: module type Goo = Foo with type t = int module type Hoo = Foo with type t := int let x = (module M : Goo) (* correct *)
module type Foo = sig
type t
val foo : t -> t
end
module M = struct
type t = int
let foo t = t + 1
end
那么我会:
module type Goo = Foo with type t = int
module type Hoo = Foo with type t := int
let x = (module M : Goo) (* correct *)
let y = (module M : Hoo) (* correct *)
let z = (module M : Foo with type t = int) (* correct *)
最重要的是正确,没有问题
然而,如果我这样做
let z = (module M : Foo with type t := int) (* wrong *)
这是错误的,错误是给定的
错误:分析错误:“=”应在[ident](在[package_type_cstr]中)之后
为什么我不能在一级模块打包中使用
:=
?在OCaml 4.01及更早版本中,一级模块是以指定方式键入的。换句话说,它们的类型基于所用模块类型的名称,而不是其结构。例如:
OCaml version 4.01.0
# module type T = sig type t end;;
module type T = sig type t end
# module type S = sig type t end;;
module type S = sig type t end
# let f (x : (module T)) : (module S) = x;;
Characters 38-39:
let f (x : (module T)) : (module S) = x;;
^
Error: This expression has type (module T)
but an expression was expected of type (module S)
这要求模块类型具有名称:
# type t = (module sig type t end);;
Characters 17-20:
type t = (module sig type t end);;
^^^
Error: Syntax error
不允许破坏性替换,因为它创建了一个没有名称的新模块类型。常规替换是可以的,因为类型为t=int的S仍然是S
,我们只是对它的定义了解得更多<类型为t:=int
的code>S不是S
它与S
有不同的组件,因为它缺少t
类型
最近(,),一级模块的类型检查已改为结构化,而不是命名:
OCaml version 4.02.0+dev5-2014-04-29
# module type T = sig type t end;;
module type T = sig type t end
# module type S = sig type t end;;
module type S = sig type t end
# let f (x : (module T)) : (module S) = x;;
val f : (module T) -> (module S) = <fun>
OCaml版本4.02.0+dev5-2014-04-29
#模块类型T=sig类型T端;;
模块类型T=sig类型T端
#模块类型S=sig类型t端;;
模块类型S=sig类型t端
#设f(x:(模T)):(模S)=x;;
val f:(模块T)->(模块S)=
这意味着可以为没有名称的类型创建一级模块。但是,这项工作尚未完成,将无法在4.02中提供。因此,在4.02之后的版本中,在一级模块类型中可能确实可以使用破坏性替换。我说的对吗,您不是在寻找解决方法?只是问一下,我很确定,你知道。也许,在ocaml邮件列表中问这个问题更好?@ivg我不是在要求解决方法,因为
:=
非常方便。一种解决方法是,我只需要一个没有t
的新签名,然后用int
替换t
。我只是想了解他们决定禁用头等舱模块的原因