(最小限の非コンパイルする例がhttps://gist.github.com/4044467で見つけることができ、以下のより多くの背景を参照してください。)OCamlで岡崎のブートストラップされたヒープを実装すると、なぜコンパイルされませんか?
私はOkasakiの純粋に機能的なデータ構造の第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)
BootstrappedHeapの実装、Okasakiによると、このようなものです:
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は、私はBootstrappedElem
はそれがt
とcompare
の両方を持っているようORDERED
を実装しましたが、私は、コンパイラが見つからなかった理由を見ることができなかったと思うライン
and PrimH : (HEAP with module Elem = BootstrappedElem) =
ですcompare
機能です。
module rec BootstrappedElem : ORDERED
にBootstrappedElemの
変更署名は、それがコンパイルになりますが、これは、それは不可能後で部品を実装できるようにすることBootstrappedElem
で型コンストラクタE
とT
を非表示になります。
全体の非コンパイルしたコードは、私は、これが型チェッカのバグかもしれないと考えていhttps://raw.github.com/gist/4044281/0ce0336c40b277e59cece43dbadb9b94ce6efdaf/ordered.ml
ありがとうございます!コンパイラのバグとよく似ていると思います。もっと多くの人が確認できれば、このバグを報告します。 –