(可以在https://gist.github.com/4044467找到一个最小的非编译示例,请参阅下面的更多背景。)
我正在尝试实现冈崎纯功能数据结构第 10 章中介绍的引导堆。以下是我的非编译代码的简化版本。
我们要实现一个具有以下签名的堆:
module type ORDERED =
sig
type t
val compare : t -> t -> int
end
module type HEAP =
sig
module Elem : ORDERED
type heap
val empty : heap
val insert : Elem.t -> heap -> heap
val find_min : heap -> Elem.t
val delete_min : heap -> heap
end
当一个数据结构的实现依赖于同一种数据结构的另一个实现时,我们说它是自举的。所以我们有一个这样的堆(实际的实现并不重要):
module SomeHeap (Element : ORDERED) : (HEAP with module Elem = Element) =
struct
module Elem = Element
type heap
let empty = failwith "skipped"
let insert = failwith "skipped"
let find_min = failwith "skipped"
let delete_min = failwith "skipped"
end
然后,我们将要实现的引导堆,它可以依赖于任何堆实现,应该具有以下签名:
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element)
所以我们可以这样使用它:
module StringHeap = BootstrappedHeap(SomeHeap)(String)
根据 Okasaki 的说法,BootstrappedHeap 的实现是这样的:
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element) =
struct
module Elem = Element
module rec BootstrappedElem :
sig
type t =
| E
| H of Elem.t * PrimH.heap
val compare : t -> t -> int
end =
struct
type t =
| E
| H of Elem.t * PrimH.heap
let compare t1 t2 = match t1, t2 with
| H (x, _), H (y, _) -> Elem.compare x y
| _ -> failwith "unreachable"
end
and PrimH : (HEAP with module Elem = BootstrappedElem) =
MakeH(BootstrappedElem)
type heap
let empty = failwith "not implemented"
let insert = failwith "not implemented"
let find_min = failwith "not implemented"
let delete_min = failwith "not implemented"
end
但这不是编译!错误信息是:
File "ordered.ml", line 52, characters 15-55:
Error: In this `with' constraint, the new definition of Elem
does not match its original definition in the constrained signature:
Modules do not match:
sig type t = BootstrappedElem.t end
is not included in
ORDERED
The field `compare' is required but not provided
第52行是行
and PrimH : (HEAP with module Elem = BootstrappedElem) =
我认为BootstrappedElem
确实实现ORDERED
了,因为它同时具有t
and compare
,但是我看不出为什么编译器无法找到该compare
函数。
将 BootstrappedElem 的签名更改为
module rec BootstrappedElem : ORDERED
将使其编译,但这将隐藏类型构造函数E
并使其无法实现后面的部分T
。BootstrappedElem
整个非编译代码可以在https://raw.github.com/gist/4044281/0ce0336c40b277e59cece43dbadb9b94ce6efdaf/ordered.ml下载