Печать элементов в списке в OCaml - PullRequest
0 голосов
/ 27 сентября 2018

Я хочу написать хвостовую рекурсивную функцию для печати элементов в списке строк в отдельных строках, например:

  # printlist ["a";"b";"c"];;
   a
   b
   c
   - : unit = ()
   # printlist ["hello";"thanks"];;
   hello
   thanks
   - : unit = ()

Я смог заставить его работать без проблем с помощью print_endline:

let rec printlist strlist =
  match strlist with 
  | [] ->  print_endline "" 
  | hd::[] ->  print_endline hd
  | hd :: tl -> print_endline hd  ; printlist tl;;

Однако, как только я переключаюсь на printf, он больше не работает.Что не так с моей версией printf?

let rec printlist strlist =
  match strlist with 
  | [] ->  printf "" 
  | hd::[] ->  printf hd
  | hd :: tl -> printf "%s\n" hd  ; printlist tl;;
Error: This expression has type
         (unit, out_channel, unit) format =
           (unit, out_channel, unit, unit, unit, unit)
           CamlinternalFormatBasics.format6
       but an expression was expected of type string

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

В дополнение к ответу Джеффри я бы посоветовал вам использовать стандартную библиотеку больше для написания более краткого кода.

List.iter, например, вызывает данную функцию для всех элементов списка:

let print_list l = List.iter (fun e -> Printf.printf "%s\n" e) l

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

let print_list = List.iter (Printf.printf "%s\n")

Единственная разница с вашей функцией - это новая строкапосле последнего элемента.


С другой стороны, вместо того, чтобы печатать элементы один за другим, более функциональным и идиоматическим подходом было бы сначала создать всю строку, а затем распечатать ее.

К счастью, стандартная библиотека покрыла вас.String.concat объединяет элементы в string list в одну большую строку.Вы также можете указать строку для использования в качестве разделителя, и вам не нужно беспокоиться о переводе строки после последнего элемента.

let print_list l = print_string (String.concat "\n" l)
0 голосов
/ 27 сентября 2018

По сути, вы пытаетесь использовать printf без формата.Первый аргумент printf должен быть константной строкой.Таким образом, у вас должно быть следующее:

printf "%s" hd

, а не это:

printf hd

Чтобы понять, почему это требуется, представьте, что произойдет, если некоторые строки в вашем входном файле содержат символы процента,Вещи вышли бы из-под контроля (по типу) довольно быстро.

...