在OCaml中打印列表

时间:2012-02-03 20:16:27

标签: ocaml

我想做一件简单的事情:

列印清单。

let a = [1;2;3;4;5]

如何将此列表打印到标准输出?

9 个答案:

答案 0 :(得分:54)

您应该熟悉List.iter和List.map函数。它们对于OCaml中的编程至关重要。如果您对Printf模块感到满意,那么您可以写下:

open Printf
let a = [1;2;3;4;5]
let () = List.iter (printf "%d ") a

我在大部分代码中都打开了Printf,因为我经常使用其中的函数。没有它,你必须在最后一行写Printf.printf。此外,如果您在toploop中工作,请不要忘记以双分号结束上述语句。

答案 1 :(得分:34)

您可以通过简单的递归来完成此操作:

let rec print_list = function 
[] -> ()
| e::l -> print_int e ; print_string " " ; print_list l

打印列表的头部,然后在列表的尾部进行递归调用。

答案 2 :(得分:26)

print_string (String.concat " " (List.map string_of_int list))

答案 3 :(得分:7)

如果问题是找到最快速的方法来实现它,例如在调试时,那么我们可以说:

  • 扩展标准库(例如电池)通常具有一些附加功能:

    List.print
      ~first:"[" ~sep:";" ~last:"]" (fun c x -> Printf.fprintf c "%d" x) stdout a
    
  • 我前段时间写的这个小syntax extension允许你写:

    <:print<[$!i <- a${$d:i$}{;}]>>
    
  • 自动生成不是立即可用的(因为OCaml数据表示中缺少运行时类型信息),但可以使用类型或运行时类型生成代码来实现。

答案 4 :(得分:6)

我很晚才回答,但这是另一种方式:

let print_list f lst =
  let rec print_elements = function
    | [] -> ()
    | h::t -> f h; print_string ";"; print_elements t
  in
  print_string "[";
  print_elements lst;
  print_string "]";;

要打印一个int列表,我们可以写:

print_list print_int [3;6;78;5;2;34;7];;

但是如果我们要做很多事情,那么使用部分应用程序可以节省专门化功能的时间:

let print_int_list = print_list print_int;;

我们现在可以这样使用:

print_int_list [3;6;78;5;2;34;7];;

如果我们想要做一些相当复杂的事情,比如打印一个int列表,该怎么办?使用此功能,很容易:

(* Option 1 *)
print_list (print_list print_int) [[3;6;78];[];[5];[2;34;7]];;

(* Option 2 *)
let print_int_list_list = print_list (print_list print_int);;
print_int_list_list [[3;6;78];[];[5];[2;34;7]];;

(* Option 3 *)
let print_int_list_list = print_list print_int_list;;
print_int_list_list [[3;6;78];[];[5];[2;34;7]];;

打印(int * string)列表(即整数和字符串对的列表):

(* Option 1 *)
print_list (fun (a, b) -> print_string "("; print_int a; print_string ", "; print_string b; print_string ")") [(1, "one"); (2, "two"); (3, "three")];;

(* Option 2 *)
let print_pair f g (a, b) =
  print_string "(";
  f a;
  print_string ", ";
  g b;
  print_string ")";;
print_list (print_pair print_int print_string) [(1, "one"); (2, "two"); (3, "three")];;

(* Option 3 *)
let print_pair f g (a, b) =
  print_string "(";
  f a;
  print_string ", ";
  g b;
  print_string ")";;
let print_int_string_pair = print_pair print_int print_string;;
print_list print_int_string_pair [(1, "one"); (2, "two"); (3, "three")];;

(* Option 4 *)
let print_pair f g (a, b) =
  print_string "(";
  f a;
  print_string ", ";
  g b;
  print_string ")";;
let print_int_string_pair = print_pair print_int print_string;;
let print_int_string_pair_list = print_list print_int_string_pair;;
print_int_string_pair_list [(1, "one"); (2, "two"); (3, "three")];;

答案 5 :(得分:3)

我会用以下方式做到这一点:

let a = [1;2;3;4;5];;
List.iter print_int a;;

答案 6 :(得分:2)

只是%a的解决方案:

open Printf
let print_l outx l = 
     List.map string_of_int  l
  |> String.concat ";"
  |> fprintf outx "%s"

测试:

# printf "[%a]" print_l [1;2;3] ;;
[1;2;3]- : unit = ()
# printf "[%a]" print_l [];;
[]- : unit = ()

答案 7 :(得分:2)

实际上,您可以解除打印列表并将列表转换为字符串。这样做的主要优点是您可以使用此方法在日志中显示列表,将它们导出为CSV ...

我经常使用listHelper模块,其中包含以下内容:

(** Generic method to print the elements of a list *)
let string_of_list input_list string_of_element sep =
  let add a b = a^sep^(string_of_element b) in
  match input_list with
  | [] -> ""
  | h::t -> List.fold_left add (string_of_element h) t

因此,如果我想将一个浮点列表输出到csv文件,我可以使用以下内容:

let float_list_to_csv_row input_list = string_of_list input_list string_of_float "," 

答案 8 :(得分:1)

let print_list l =
  let rec aux acc =
    match acc with
     | [] -> ()
     | x :: tl ->
       Printf.fprintf stdout "%i"; aux tl
   in aux l

或者

let sprintf_list l =
  let acc = ref "{" in
  List.iteri (fun i x ->
    acc := !acc ^
      if i <> 0
      then Printf.sprintf "; %i" x
      else Printf.sprintf "%i" x
  ) l;
  !acc ^ "}"

let print_list l =
  let output = sprintf_list l in
  Printf.fprintf stdout "%s\n" output