Распечатать список в OCaml - PullRequest
       0

Распечатать список в OCaml

33 голосов
/ 04 февраля 2012

Я хочу сделать что-то простое:

Распечатать список.

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

Как мне распечатать этот список в стандартный вывод?

Ответы [ 9 ]

54 голосов
/ 04 февраля 2012

Вы должны ознакомиться с функциями List.iter и List.map.Они необходимы для программирования на OCaml.Если вам также удобно работать с модулем Printf, вы можете написать:

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

Я открываю Printf в большей части своего кода, потому что я использую функции в нем так часто.Без этого вам пришлось бы писать Printf.printf в последней строке.Кроме того, если вы работаете в toploop, не забудьте завершить приведенные выше операторы двойными точками с запятой.

35 голосов
/ 04 февраля 2012

Вы можете сделать это с помощью простой рекурсии:

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

Печатается заголовок списка, затем вы делаете рекурсивный вызов в конце списка.

26 голосов
/ 20 февраля 2012
print_string (String.concat " " (List.map string_of_int list))
7 голосов
/ 20 февраля 2012

Если вопрос в том, чтобы найти самый быстрый способ реализовать это, например, при отладке, то мы можем сказать, что:

  • расширенные стандартные библиотеки (например, батареи) обычно имеют некоторые дополнительные функции:

    List.print
      ~first:"[" ~sep:";" ~last:"]" (fun c x -> Printf.fprintf c "%d" x) stdout a
    
  • это крошечное расширение синтаксиса , которое я написал некоторое время назад, позволяет написать:

    <:print<[$!i <- a${$d:i$}{;}]>>
    
  • автоматическая генерация не доступна сразу (из-за отсутствия информации о типах во время выполнения в представлении данных OCaml), но может быть достигнута с помощью либо генерации кода из типов, либо типов во время выполнения.
6 голосов
/ 29 октября 2013

Я очень поздно отвечаю, но вот другой способ:

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

Чтобы напечатать список int, мы могли бы написать:

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

Однако, если мы собираемся сделатьэто очень много, это сэкономило бы время, чтобы специализировать функцию с помощью частичного применения:

let print_int_list = print_list print_int;;

Что мы можем теперь использовать следующим образом:

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

Что если мы хотим сделать что-то красивоесложный, как печать списка 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]];;

Печать списка (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")];;
3 голосов
/ 12 февраля 2017

Я бы сделал это следующим образом:

let a = [1;2;3;4;5];;
List.iter print_int a;;
2 голосов
/ 14 мая 2018

На самом деле, вы можете отделить печать списка и превратить список в строку. Основным преимуществом для этого является то, что вы можете использовать этот метод для отображения списков в журналах, экспортировать их в CSV-файлы ...

Я часто использую модуль listHelper со следующим:

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

Итак, если бы я хотел вывести список с плавающей точкой в ​​файл CSV, я мог бы просто использовать следующее:

let float_list_to_csv_row input_list = string_of_list input_list string_of_float "," 
2 голосов
/ 14 февраля 2017

Просто решение с% a:

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

Тест:

# printf "[%a]" print_l [1;2;3] ;;
[1;2;3]- : unit = ()
# printf "[%a]" print_l [];;
[]- : unit = ()
1 голос
/ 03 июля 2015
let print_list l =
  let rec aux acc =
    match acc with
     | [] -> ()
     | x :: tl ->
       Printf.fprintf stdout "%i"; aux tl
   in aux l

Или

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...