(Un non-compilazione esempio minimo può essere trovato alla https://gist.github.com/4044467, vedere di più sfondo di seguito.)Implementare gli heap bootstrap di Okasaki in OCaml, perché non lo compila?
Sto cercando di implementare bootstrap Cumuli introdotti nel capitolo 10 del puramente funzionale struttura dati di Okasaki. Quanto segue è una versione semplificata del mio codice non compilato.
stiamo per implementare un heap con seguente firma:
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
Diciamo una struttura dati è bootstrap quando la sua attuazione dipende da un'altra implementazione dello stesso tipo di struttura dati. Quindi abbiamo un mucchio come questo (l'effettiva implementazione non è importante):
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
Poi, l'heap bootstrap che andremo a realizzare, che può dipendere da qualsiasi implementazione mucchio, dovrebbe avere la seguente firma :
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element)
in modo che possiamo usare in questo modo:
module StringHeap = BootstrappedHeap(SomeHeap)(String)
L'attuazione di BootstrappedHeap, secondo Okasaki, è come questo:
012.351.641,061 milamodule 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
Ma questa non è la compilazione! Il messaggio di errore è:
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
La linea 52 è la linea
and PrimH : (HEAP with module Elem = BootstrappedElem) =
Penso BootstrappedElem
ha attuato ORDERED
in quanto ha sia t
e compare
, ma non sono riuscito a vedere il motivo per cui il compilatore non riesce a trovare la funzione compare
.
Modificare la firma del BootstrappedElem per
module rec BootstrappedElem : ORDERED
renderà la compilazione, ma questo nasconde il tipo di costruttore di E
e T
in BootstrappedElem
per l'impossibilità di attuare le parti successive.
Il non-compilazione del codice intero possono essere scaricate dal https://raw.github.com/gist/4044281/0ce0336c40b277e59cece43dbadb9b94ce6efdaf/ordered.ml
Grazie mille! Penso che sembra molto simile a un bug del compilatore. Segnalerò questo bug se più persone possono confermarlo. –