set - OCaml:在 mli 文件中表达“t 集”
问题描述
OCaml 的新手和 Sets 的绊脚石(真的,模块类型和仿函数)。我想在.mli
文件中定义以下内容:
type t
type tag
val tags : t -> <set of tag>
set of tag
我无法弄清楚的类型在哪里,类似于tag list
.
更新:感谢杰弗里斯科菲尔德在下面的有用评论,但由于我的真正问题仍未得到解答,我认为我表达得不好。这是第二次尝试:
鉴于此a.ml
:
type tag = string
module TagSet = Set.Make (struct
type t = tag
let compare = String.compare
end)
type t = { name : string; tags : TagSet.t }
let empty = { name = ""; tags = TagSet.empty }
let get_tags { tags; _ } = tags
我该如何填写a.mli
?
type t
type tag
val empty : t
val get_tags : t -> ???
where???
表示“TagSet.t”,同时仍保持tag
抽象,即“使用 t = 的 OrderedType 调用 Set.Make 的结果tag
”。
这可能吗?似乎必须如此。我正在寻找 OCaml 最接近 Scala 的Set[T]
.
解决方案
在开始探索 OCaml 的模块体系时,从编译器自己直接推断出的模块类型开始,逐步修改以更好地满足您的需求,是非常有用的。
例如,从您的实现中推断出的模块是:
type tag = string
module TagSet :
sig
type elt = tag
type t
val empty : t
...
val add_seq : elt Seq.t -> t -> t
val of_seq : elt Seq.t -> t
end
type t = { name : tag; tags : TagSet.t; }
val empty : t
val get_tags : t -> TagSet.t
(您可以从 Merlin、ocaml-lsp、utop 或 中获取此推断的模块类型ocamlc -i path_to_file.ml
)。
从这一点开始,我们可以去掉信息来做类型tag
和t
抽象:
type tag
type t
module TagSet :
sig
type elt = tag
type t
val empty : t
...
val add_seq : elt Seq.t -> t -> t
val of_seq : elt Seq.t -> t
end
val empty : t
val get_tags : t -> TagSet.t
然后另一个问题是模块类型TagSet
非常大而且冗长。如果能够将此签名定义为Set
带有 type 元素的模块类型,那就太好了tag
。幸运的是,出于这个原因,该模块Set
定义了一个命名签名S
来描述结果的签名。Make
如果我们使用这个预定义的签名,我们可以将前面的定义简化为
type tag
type t
module TagSet : Set.S with type elt = tag
val empty : t
val get_tags : t -> TagSet.t
推荐阅读
- jira - 根据状态过滤故事,但包括其所有子任务
- python - 打印到打印机 python turtle 图形图像
- azure-logic-apps - 本地 SQL Server 到 Azure
- magento - Magento 1 上的 SagePay
- mysql - Spark MariaDB jdbc SQL 查询返回列名而不是列值
- angular - 如何循环通过角度获取请求响应
- javascript - 如何通过 JavaScript 从 URL 中获取变量?
- map-api - 使用捕获的坐标绘制矩形
- spring-boot - 如何使用 jdbcTemplate 方法测试我的存储库?
- ios - SwiftUI 中 ScrollView 中的多个列表