Imprimir una lista en OCaml


Quiero hacer algo tan simple como esto:

Imprime una lista.

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

¿Cómo puedo imprimir esta lista en la salida Estándar?

 31
Author: Gitmo, 2012-02-04

9 answers

Puedes hacer esto con una simple recursión:

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

Se imprime el encabezado de la lista, luego se hace una llamada recursiva en la cola de la lista.

 31
Author: Ackar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-03 20:27:41

Usted debe familiarizarse con la Lista.iter y Lista.funciones de mapa. Son esenciales para la programación en OCaml. Si también se siente cómodo con el módulo Printf, puede escribir:

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

Abro Printf en la mayor parte de mi código porque uso las funciones en él muy a menudo. Sin eso tendrías que escribir Printf.printf en la última línea. Además, si está trabajando en el toploop, no se olvide de terminar las declaraciones anteriores con doble punto y coma.

 50
Author: Ashish Agarwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-03 22:21:32
print_string (String.concat " " (List.map string_of_int list))
 25
Author: Fabrice Le Fessant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-20 08:24:19

Si la pregunta es acerca de encontrar la manera más rápida de implementar esto, por ejemplo al depurar, entonces podríamos decir que:

  • Las bibliotecas estándar extendidas (por ejemplo, baterías) suelen tener algunas funciones adicionales:

    List.print
      ~first:"[" ~sep:";" ~last:"]" (fun c x -> Printf.fprintf c "%d" x) stdout a
    
  • Esta pequeña extensión de sintaxis que escribí hace algún tiempo te permite escribir:

    <:print<[$!i <- a${$d:i$}{;}]>>
    
  • la generación automática no está disponible inmediatamente (debido a la falta de información de tipo de tiempo de ejecución en los datos OCaml representación), pero se puede lograr utilizando la generación de código a partir de los tipos, o tipos en tiempo de ejecución.
 7
Author: Tiphaine Turpin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-20 13:13:46

Llego muy tarde a responder, pero aquí hay otra manera:

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 "]";;

Para imprimir una lista int, podríamos escribir:

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

Sin embargo, si vamos a hacer esto mucho, ahorraríamos tiempo para especializar la función usando la aplicación parcial:

let print_int_list = print_list print_int;;

Que ahora podemos usar así:

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

¿Y si quisiéramos hacer algo bastante complejo, como imprimir una lista int? Con esta función, es fácil:

(* 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]];;

Imprimir una lista (int * string) (es decir, una lista de pares de ints y strings):

(* 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
Author: Bertie Wheen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-29 01:12:02
let print_list l =
  let rec aux acc =
    match acc with
     | [] -> ()
     | x :: tl ->
       Printf.fprintf stdout "%i"; aux tl
   in aux l

O

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
 1
Author: Quyen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-03 07:59:35

Solo una solución con % a:

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

Prueba:

# printf "[%a]" print_l [1;2;3] ;;
[1;2;3]- : unit = ()
# printf "[%a]" print_l [];;
[]- : unit = ()
 1
Author: V. Michel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-14 03:49:36

Yo haría esto de la siguiente manera:

let a = [1;2;3;4;5];;
List.iter print_int a;;
 1
Author: akshaynagpal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-03 15:17:55

En realidad, puede desacoplar la impresión de una lista y convertir una lista en una cadena. La principal ventaja de hacer esto es que puede usar este método para mostrar listas en registros y exportarlas a CSVs...

A menudo uso un módulo listHelper, con lo siguiente :

(** 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

Entonces, si quisiera generar una lista de flotadores en un archivo csv, podría usar lo siguiente:

let float_list_to_csv_row input_list = string_of_list input_list string_of_float "," 
 1
Author: RUser4512,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-14 09:18:15