1

私は2つのファイルを持っています:myUnionFind.mlmyUnionFind_test.ml。両方のファイルがにありsame directoryます。

myUnionFind.ml

open Batteries

module type MyUnionFindSig = 
sig

  type union_find

  val print_array : 'a array -> unit
  val create_union : int -> union_find
  val union_weighted : union_find -> int -> int -> unit
  val is_connected_weighted : union_find -> int -> int -> bool
end;;


module MyUnionFind : MyUnionFindSig =
struct 
  let print_array ary = print_endline (BatPervasives.dump ary);;

  type union_find = {id_ary : int array; sz_ary : int array};;

  let create_union n = {id_ary = Array.init n (fun i -> i); 
            sz_ary = Array.make n 1};;

(* weighted quick union find *)

  let find_root ary i = 
    let rec find j =
      if ary.(j) = j then j
      else  find ary.(j)
    in
    find i;;

  let union_weighted {id_ary;sz_ary} p q = 
    let root_p = find_root id_ary p in
    let root_q = find_root id_ary q in
    if sz_ary.(root_p) < sz_ary.(root_q) then begin
      id_ary.(root_p) <- id_ary.(root_q);
      sz_ary.(root_q) <- sz_ary.(root_q) + sz_ary.(root_p)
    end 
    else begin
      id_ary.(root_q) <- id_ary.(root_p);
      sz_ary.(root_p) <- sz_ary.(root_p) + sz_ary.(root_q)
    end;;


let is_connected_weighted {id_ary;_} p q = (find_root id_ary p) = (find_root id_ary q);;

end

myUnionFind_test.ml

open Batteries

let uf2 = MyUnionFind.create_union 10;;

MyUnionFind.union_weighted uf2 0 3;;
MyUnionFind.union_weighted uf2 1 4;;
MyUnionFind.union_weighted uf2 4 3;;
MyUnionFind.union_weighted uf2 2 8;;

MyUnionFind.print_array uf2.MyUnionFind.id_ary;;

BatPervasives.print_bool (MyUnionFind.is_connected_weighted uf2 0 3);;

私は試した

ocamlfind ocamlc -package batteries -c myUnionFind.ml。それはうまくいきました、私は見ることができmyUnionFind.cmiますmyUnionFind.cmo

myUnionFind_test.mlそれから私は経由 してコンパイルしようとしました

ocamlfind ocamlc -package batteries -c myUnionFind_test.ml

このエラーが発生します:

ファイル"myUnionFind_test.ml"、3行目、文字10-34:エラー:バインドされていない値MyUnionFind.create_union


理由がわかりません。create_unionモジュールで定義しましMyUnionFindたが、なぜ見つからないのですか?

4

2 に答える 2

3

モジュールでモジュールを定義します (myUnionFind.ml はモジュールです)。

したがって、テスト ファイルでは、次のようにモジュールを開く必要があります。

open Batteries
open MyUnionFind (* Here !*)
let uf2 = MyUnionFind.create_union 10;;

MyUnionFind.union_weighted uf2 0 3;;
MyUnionFind.union_weighted uf2 1 4;;
MyUnionFind.union_weighted uf2 4 3;;
MyUnionFind.union_weighted uf2 2 8;;

MyUnionFind.print_array uf2.MyUnionFind.id_ary;;

BatPervasives.print_bool (MyUnionFind.is_connected_weighted uf2 0 3);;

または各呼び出しの前に次のように付けます:

let uf2 = MyUnionFind.MyUnionFind.create_union 10;;

myUnionFind.ml でモジュールを定義するだけで、以前のように 2 つのモジュールが必要ない場合は、次のように .ml と .mli ファイルを作成できます。

 (* myUnionFind.mli *)
 type union_find  = {id_ary : int array; sz_ary : int array}

 val print_array : 'a array -> unit
 val create_union : int -> union_find
 val union_weighted : union_find -> int -> int -> unit
 val is_connected_weighted : union_find -> int -> int -> bool

 (* myUnionFind.ml *)
 type union_find = {id_ary : int array; sz_ary : int array};;

 let print_array ary = (* ... *)
 let create_union n =  (* ... *)
 let union_weighted r p q = (* ... *)
 let find_root ary i = (* ... *)

id_aryフィールドへの参照がある場合は、それをモジュール署名に入れる必要があることに注意してください

于 2013-02-14T13:52:09.650 に答える
1

OCaml は、ファイルごとに 1 レベルのモジュールを無料で提供します。したがって、myUnionFind.mlこの無料のモジュール内にモジュールがあります。これを回避するには、ファイルの最上位ですべてを宣言します。次に、ファイルと同じ名前のモジュールを 1 つだけ作成します。

于 2013-02-14T19:58:55.870 に答える