Imprimer une liste dans OCaml
Je veux faire quelque chose d'aussi simple que cela:
Affiche une liste.
let a = [1;2;3;4;5]
Comment puis-je imprimer cette liste en sortie Standard?
9 réponses
Vous pouvez le faire avec une récursivité simple:
let rec print_list = function
[] -> ()
| e::l -> print_int e ; print_string " " ; print_list l
La tête de la liste est imprimée, puis vous faites un appel récursif sur la queue de la liste.
Vous devriez Vous familiariser avec la Liste.iter et List.les fonctions de mappage. Ils sont essentiels pour la programmation en OCaml. Si vous êtes également à l'aise avec le module Printf, vous pouvez alors écrire:
open Printf
let a = [1;2;3;4;5]
let () = List.iter (printf "%d ") a
J'ouvre Printf dans la plupart de mon code parce que j'utilise les fonctions si souvent. Sans cela, vous devrez écrire Printf.printf
dans la dernière ligne. De plus, si vous travaillez dans le toploop, n'oubliez pas de terminer les instructions ci-dessus avec des doubles points-virgules.
print_string (String.concat " " (List.map string_of_int list))
Si la question Est de trouver le moyen le plus rapide de l'implémenter, par exemple lors du débogage, alors nous pourrions dire que:
-
Les bibliothèques standard étendues (par exemple les batteries) ont généralement des fonctions supplémentaires:
List.print ~first:"[" ~sep:";" ~last:"]" (fun c x -> Printf.fprintf c "%d" x) stdout a
-
Cette minuscule extension de syntaxe que j'ai écrite il y a quelque temps vous permet d'écrire:
<:print<[$!i <- a${$d:i$}{;}]>>
- la génération automatique n'est pas immédiatement disponible (en raison du manque d'informations de type d'exécution dans les données OCaml représentation) mais peut être réalisé en utilisant soit la génération de code à partir des types, soit des types d'exécution.
Je suis très en retard pour répondre, Mais voici une autre façon:
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 "]";;
Pour imprimer une liste int, nous pourrions écrire:
print_list print_int [3;6;78;5;2;34;7];;
Cependant, si nous devions le faire beaucoup, cela gagnerait du temps à spécialiser la fonction en utilisant une application partielle:
let print_int_list = print_list print_int;;
Que nous pouvons maintenant utiliser comme ceci:
print_int_list [3;6;78;5;2;34;7];;
Et si nous voulions faire quelque chose d'assez complexe, comme imprimer une liste de liste int? Avec cette fonction, c'est facile:
(* 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]];;
Impression d'une liste (int * string) (c'est-à-dire une liste de paires des ints et des chaînes):
(* 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")];;
let print_list l =
let rec aux acc =
match acc with
| [] -> ()
| x :: tl ->
Printf.fprintf stdout "%i"; aux tl
in aux l
Ou
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
Juste une solution avec %une :
open Printf
let print_l outx l =
List.map string_of_int l
|> String.concat ";"
|> fprintf outx "%s"
Test:
# printf "[%a]" print_l [1;2;3] ;;
[1;2;3]- : unit = ()
# printf "[%a]" print_l [];;
[]- : unit = ()
Je le ferais de la manière suivante:
let a = [1;2;3;4;5];;
List.iter print_int a;;
En fait, vous pouvez découpler l'impression d'une liste et transformer une liste en une chaîne. Le principal avantage pour ce faire est que vous pouvez utiliser cette méthode pour afficher les listes dans les journaux, les exporter vers CSVs...
J'utilise souvent un module listHelper, avec ce qui suit:
(** 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
Donc, si je voulais sortir une liste de flotteurs dans un fichier csv, je pourrais simplement utiliser ce qui suit:
let float_list_to_csv_row input_list = string_of_list input_list string_of_float ","