val - Imprima una lista en OCaml
ocaml vs haskell (9)
Debe familiarizarse con las funciones List.iter y List.map. Son esenciales para programar en OCaml. Si también te sientes cómodo con el módulo Printf, puedes escribir lo siguiente:
open Printf
let a = [1;2;3;4;5]
let () = List.iter (printf "%d ") a
Abrí Printf en la mayoría de mi código porque uso las funciones con tanta frecuencia. Sin eso tendrías que escribir Printf.printf
en la última línea. Además, si está trabajando en el toploop, no olvide finalizar las afirmaciones anteriores con comas dobles y comas.
Quiero hacer algo tan simple como esto:
Imprimir una lista
let a = [1;2;3;4;5]
¿Cómo puedo imprimir esta lista a la salida estándar?
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, exportarlas a archivos CSV ...
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 flotantes 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 ","
Estoy respondiendo muy tarde, 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 íbamos a hacer esto mucho, nos ahorraría tiempo especializar la función utilizando una 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];;
¿Qué pasa si queremos hacer algo bastante complejo, como imprimir una lista de 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 cadenas):
(* 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")];;
Haría esto de la siguiente manera:
let a = [1;2;3;4;5];;
List.iter print_int a;;
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 realiza una llamada recursiva en la cola de la lista.
Si la pregunta es sobre encontrar la forma 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 de inmediato (debido a la falta de información de tipo de tiempo de ejecución en la representación de datos de OCaml), pero se puede lograr utilizando la generación de código de los tipos o los tipos de tiempo de ejecución.
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 = ()
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
print_string (String.concat " " (List.map string_of_int list))