1

OCaml でデータベースのクエリ結果を出力するプリティ プリント関数を取得しようとしています。私はこのアプローチに従っていますhttp://mancoosi.org/~abate/ocaml-format-module

私はこれまでにこのコードを持っています:

let pp_cell fmt cell = Format.fprintf fmt "%s" cell;;

let pp_header widths fmt header =
  let first_row = Array.map (fun x -> String.make (x + 1) ' ') widths in
  Array.iteri (fun j cell ->
    Format.pp_set_tab fmt ();
    for z=0 to (String.length header.(j)) - 1 do cell.[z] <- header.(j).[z] done;
    Format.fprintf fmt "%s" cell
  ) first_row

let pp_row pp_cell fmt row =
  Array.iteri (fun j cell ->
    Format.pp_print_tab fmt ();
    Format.fprintf fmt "%a" pp_cell cell
  ) row


let pp_tables pp_row fmt (header,table) =
  (* we build with the largest length of each column of the 
   * table and header *)
  let widths = Array.create (Array.length table.(0)) 0 in
  Array.iter (fun row ->
    Array.iteri (fun j cell ->
      widths.(j) <- max (String.length cell) widths.(j)
    ) row
  ) table;
  Array.iteri (fun j cell ->
    widths.(j) <- max (String.length cell) widths.(j)
  ) header;

  (* open the table box *)
  Format.pp_open_tbox fmt ();

  (* print the header *)
  Format.fprintf fmt "%a@\n" (pp_header widths) header;
  (* print the table *)
  Array.iter (pp_row fmt) table;

  (* close the box *)
  Format.pp_close_tbox fmt ();
;;


(** Pretty print answer set of a query in format of
 *    col_name 1 | col_name 2 | col_name 3 |
 *    result1.1  | result2.1  | result3.1  |
 *    result1.2  | result2.2  | result3.2  |
 *   @param col_names provides the names of columns in result outp ut *)
let pretty_print fmt pp_cell (col_names, tuples) =
    match col_names with
  | [] -> printf "Empty query\n"
  | _ ->
        printf "Tuples ok\n";
        printf "%i tuples with %i fields\n" (List.length tuples) (List.length col_names);
        print_endline(String.concat "\t|" col_names);
        for i = 1 to List.length col_names do printf "--------" done; print_newline() ;
        let print_row = List.iter (printf "%s\t|") in
        List.iter (fun r -> print_row r ; print_newline ()) tuples;
        for i = 1 to List.length col_names do printf "--------" done; print_newline() ;

    let fmt = Format.std_formatter in
    Format.fprintf fmt "%a" (pp_tables (pp_row pp_cell)) (Array.of_list col_names,tuples);

      flush stdout
;;

let print_res (col_names, tuples) =
    let fmt = Format.std_formatter in
    pretty_print fmt pp_cell (col_names, tuples)
;;

問題はラインにあります

Format.fprintf fmt "%a" (pp_tables (pp_row pp_cell)) (Array.of_list col_names,tuples);

基本的に、タプルが文字列配列配列(行列)である必要があるため、そのタイプは文字列リストリストです。そこで、このアプローチhttp://www.siteduzero.com/forum-83-589601-p1-ocaml-convertir-un-list-list-en-array-arrayに従って、リストリストをマトリックスに変換して解決しようとしました.htmlに次のコードを追加します。

let listToMatrix lli =
  let result = Array.init 6 (fun _ -> Array.create 7 2)
  let rec outer = function
    | h :: tl, col ->
      let rec inner = function
        | h :: tl, row ->
          result.[row].[col] <- h
          inner (tl, row + 1)
        | _ -> ()

      inner (h, 6 - List.length h)
      outer (tl, col + 1)
    | _ -> ()
  outer (lli, 0)
  result
;;

しかし、コンパイル中に構文エラーが発生しました:

File "src/conn_ops.ml", line 137, characters 2-5:
Error: Syntax error
make: *** [bin/conn_ops.cmo] Error 2

何をすべきか、またはリストリストからマトリックスへの会話をどのように達成できるかがよくわかりません。私のアプローチは正しいですか?これは私が OCaml を使った初めての作業で、*でかなり苦労したので、親切にしてください :D

4

3 に答える 3

4

これは詳細に読むべき多くのコードですが、の後にセミコロンがないようですresult.[row].[col] <- h。しかし、このコードは私には疑わしいように見えます。表記.[xxx]は、文字列の個々の文字にアクセスするためのものです。配列の添字表記を使いたいと思い.(xxx)ます。

string list listこれは、をに変更する関数ですstring array array。多分それは役に立つでしょう:

let sll_to_saa sll = Array.of_list (List.map Array.of_list sll)

実際、この関数はリストのリストを配列の配列に変更します。文字列である必要はありません。

于 2012-12-15T17:23:42.863 に答える
3

string list list投稿全体を理解できたかどうかはわかりませんが、 aを aに変換したい場合は、関数string array arrayを使用してこれを非常に簡単に行うことができます。Array.of_list

# let strings = [["hello"; "world"]; ["foo"; "bar"]];;
val strings : string list list = [["hello"; "world"]; ["foo"; "bar"]]
# Array.of_list (List.map Array.of_list strings);;
- : string array array = [|[|"hello"; "world"|]; [|"foo"; "bar"|]|]

これが役に立ったことを願っています。

于 2012-12-15T17:28:44.267 に答える
0

関数は構文的に正しくありません。以下は修正版です。

let listToMatrix lli =
  let result = Array.init 6 (fun _ -> Array.create 7 2) in
  let rec outer = function
    | h :: tl, col ->
      let rec inner = function
    | h :: tl, row ->
      result.(row).(col) <- h;
      inner (tl, row + 1)
    | _ -> ()
      in
      inner (h, 6 - List.length h);
      outer (tl, col + 1)
    | _ -> ()
  in 
  outer (lli, 0);
  result
;;

他の回答で述べたように:

  • 配列の添字演算子は括弧です。
  • 一部のセミコロンがありません。
  • inキーワードを使用して、定義が使用される式をマークするのを忘れることがあります。

関数が本来の動作をするかどうかを確認していないことに注意してください。

于 2012-12-15T19:10:08.427 に答える