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?

31
demandé sur Gitmo 2012-02-04 00:16:26

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.

31
répondu Ackar 2012-02-03 20:27:41

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.

50
répondu Ashish Agarwal 2012-02-03 22:21:32
print_string (String.concat " " (List.map string_of_int list))
25
répondu Fabrice Le Fessant 2012-02-20 08:24:19

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.
7
répondu Tiphaine Turpin 2012-02-20 13:13:46

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")];;
5
répondu Bertie Wheen 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

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
1
répondu Quyen 2015-07-03 07:59:35

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 = ()
1
répondu V. Michel 2017-02-14 03:49:36

Je le ferais de la manière suivante:

let a = [1;2;3;4;5];;
List.iter print_int a;;
1
répondu akshaynagpal 2017-07-03 15:17:55

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 "," 
1
répondu RUser4512 2018-05-14 09:18:15