在OCaml中打印列表

Git*_*tmo 34 ocaml

我想做一件简单的事情:

打印列表.

let a = [1;2;3;4;5]
Run Code Online (Sandbox Code Playgroud)

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

Ash*_*wal 54

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

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

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

  • 如果您使用Core中的List模块(例如,您正在关注Real World Ocaml),您需要执行:`List.iter~f:(printf"%d")a` (2认同)

Ack*_*kar 36

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

let rec print_list = function 
[] -> ()
| e::l -> print_int e ; print_string " " ; print_list l
Run Code Online (Sandbox Code Playgroud)

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

  • 我想补充说重写`List.iter`似乎很遗憾. (25认同)
  • 我同意这一点.但了解列表如何工作仍然很有趣. (4认同)

Fab*_*ant 27

print_string (String.concat " " (List.map string_of_int list))
Run Code Online (Sandbox Code Playgroud)


Tip*_*pin 7

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

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

    List.print
      ~first:"[" ~sep:";" ~last:"]" (fun c x -> Printf.fprintf c "%d" x) stdout a
    
    Run Code Online (Sandbox Code Playgroud)
  • 我前段时间写的这个微小的语法扩展允许你写:

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


Ber*_*een 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 "]";;
Run Code Online (Sandbox Code Playgroud)

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

print_list print_int [3;6;78;5;2;34;7];;
Run Code Online (Sandbox Code Playgroud)

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

let print_int_list = print_list print_int;;
Run Code Online (Sandbox Code Playgroud)

我们现在可以这样使用:

print_int_list [3;6;78;5;2;34;7];;
Run Code Online (Sandbox Code Playgroud)

如果我们想做一些非常复杂的事情,比如打印一个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]];;
Run Code Online (Sandbox Code Playgroud)

打印(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")];;
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,唯一的“缺点”是列表中总是有一个附加的“;”。例如`[[[4; 2;]; [2;];]` (2认同)
  • 我在函数`print_elements`中添加了一个分支,现在很完美了:) (2认同)