(Ein minimales Nicht-Kompilierung Beispiel kann bei https://gist.github.com/4044467 gefunden wird, weiter unten noch mehr Hintergrund sehen.)Implementieren Okasaki Bootstrapped Heaps in OCaml, warum kompiliert es nicht?
I in Kapitel 10 des Okasaki rein funktionalen Datenstruktur Bootstrapped Heaps eingeführt umzusetzen versuchen. Das Folgende ist eine vereinfachte Version meines nicht kompilierenden Codes.
Wir sind ein Haufen mit folgenden Unterschrift zu implementieren:
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
Wir sagen, eine Datenstruktur ist Bootstrap, wenn seine Umsetzung auf einer weiteren Implementierung der gleichen Art von Datenstruktur abhängt. So haben wir einen Haufen wie diese (die tatsächliche Umsetzung ist nicht wichtig):
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
Dann wird der Bootstrap-Haufen wir implementieren gehen, die auf jedem Haufen Implementierung abhängen kann, soll die folgende Signatur haben : So können wir es so
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element)
verwenden:
module StringHeap = BootstrappedHeap(SomeHeap)(String)
Die Implementierung von BootstrappedHeap nach Okasaki, ist wie folgt:
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
Aber das kompiliert nicht! Die Fehlermeldung lautet:
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
Die Linie 52 ist die Linie
and PrimH : (HEAP with module Elem = BootstrappedElem) =
Ich denke BootstrappedElem
ORDERED
umgesetzt habe, da es sowohl t
und compare
hat, aber ich konnte nicht erkennen, warum der Compiler finden kann die compare
Funktion.
ändern Sie die Signatur von BootstrappedElem zu
module rec BootstrappedElem : ORDERED
wird es kompilieren machen, aber dies wird den Typkonstruktor E
und T
in BootstrappedElem
verstecken, um es unmöglich, die später Teile zu implementieren.
Der gesamte nicht-Kompilierung-Code kann ich glaube an https://raw.github.com/gist/4044281/0ce0336c40b277e59cece43dbadb9b94ce6efdaf/ordered.ml
Vielen Dank! Ich denke, es scheint sehr ähnlich zu einem Compiler-Bug. Ich werde diesen Fehler melden, wenn mehr Leute ihn bestätigen können. –