假设我在名为implementation的文件中有以下模块签名和monoids.ml
module type MonoidADT = sig
type 'a monoid
(* . . . *)
end
module Monoid : MonoidADT = struct
type 'a monoid = Monoid of ('a list) * ('a -> 'a -> 'a) * ('a)
(* . . . *)
end如何在其他文件(模块)中使用在实现中定义的类型的构造函数?它是可直接访问的,还是应该创建类似于以'a monoid作为返回类型的工厂函数?
我试图做的只是打开模块并像在模块中那样调用它的构造函数,但是它当然不能工作,并给出了Unbound constructor Monoid错误:
open Monoids.Monoid;;
let boolean_monoid = Monoid ([true; false], ( || ), false);;发布于 2022-10-30 10:56:52
签名约束删除信息。此外,如果您删除太多的信息,您可以完美地结束与不可用的模块。
通常,当你写
module Monoid : MonoidADT = struct
...
end你要求编译器将你的单子限制在每个单子共享的签名上。如果您的单类模块类型是标准模块类型:
module type MonoidADT = sig
type t
val e: t
val ( * ): t -> t -> t
end这意味着您将限制自己编写与一个元素monoid兼容的代码:
module One = struct
type t = unit
let e = ()
let ( * ) () () = ()
end这不太可能是你想要的。
如果您只希望检查您的模块是否是某些模块类型的子类型,则可以编写:
module _ : MonoidADT = Monoid发布于 2022-10-30 11:18:52
显然,在签名和实现中定义类型可以解决错误:
module type MonoidADT = sig
type 'a monoid = Monoid of ('a list) * ('a -> 'a -> 'a) * ('a)
(* . . . *)
end
module Monoid : MonoidADT = struct
type 'a monoid = Monoid of ('a list) * ('a -> 'a -> 'a) * ('a)
(* . . . *)
end但是如果我想给出一个不同的实现呢?非抽象签名限制了我对具体模块的定义。
https://stackoverflow.com/questions/74252277
复制相似问题