如何在 ocaml 中混合多态函数和仿函数?
How to mix polymorphic functions with functors in ocaml?
我有一个函子可以从 Comparable 模块创建堆模块,还有一个多态函数可以将 Prim 算法应用于具有任意标签的图形。理想情况下,我希望能够编写如下内容:
let prim (graph: 'a graph)=
let module EdgeHeap=Heap.Make(
struct
type t='a edge
...
end
) in
...
let heap=EdgeHeap.create () in
...
但是 ocamlc 说 'a 是未绑定的。我该如何解决这个问题?
通常,您会在自己的函子中拥有 prim
(以及相关函数),该函子通过图形模块签名进行参数化。 IE。类似于:
module type GraphSpec = sig
type t
...
end
module GraphAlgorithms(G: GraphSpec) = struct
type graph = ...
module EdgeHeap = Heap.Make(struct
type t = G.t edge
...
end)
let prim (g: graph) = ...
let kruskal (g: graph) = ...
end
这样就避免了类型变量的使用;相反,您通过 GraphSpec
仿函数参数传递类型。
但是如果你只需要它来实现一个功能,这可能有点过分了。您可以使用 locally abstract types 解决它。一个简单的例子来说明它是如何工作的:
let min_list (type u) (l: u list) =
let module S = Set.Make(struct
type t = u
let compare = compare
end) in
S.of_list l |> S.min_elt
我有一个函子可以从 Comparable 模块创建堆模块,还有一个多态函数可以将 Prim 算法应用于具有任意标签的图形。理想情况下,我希望能够编写如下内容:
let prim (graph: 'a graph)=
let module EdgeHeap=Heap.Make(
struct
type t='a edge
...
end
) in
...
let heap=EdgeHeap.create () in
...
但是 ocamlc 说 'a 是未绑定的。我该如何解决这个问题?
通常,您会在自己的函子中拥有 prim
(以及相关函数),该函子通过图形模块签名进行参数化。 IE。类似于:
module type GraphSpec = sig
type t
...
end
module GraphAlgorithms(G: GraphSpec) = struct
type graph = ...
module EdgeHeap = Heap.Make(struct
type t = G.t edge
...
end)
let prim (g: graph) = ...
let kruskal (g: graph) = ...
end
这样就避免了类型变量的使用;相反,您通过 GraphSpec
仿函数参数传递类型。
但是如果你只需要它来实现一个功能,这可能有点过分了。您可以使用 locally abstract types 解决它。一个简单的例子来说明它是如何工作的:
let min_list (type u) (l: u list) =
let module S = Set.Make(struct
type t = u
let compare = compare
end) in
S.of_list l |> S.min_elt