Как проверить, что следующая «голова» в OCaml пуста? - PullRequest
8 голосов
/ 21 января 2012

Я новичок в OCaml (и все еще новичок в изучении программирования в целом), и у меня есть быстрый вопрос о проверке, какой строкой является следующий элемент в списке строк.

Я хочу поместить разделитель между каждым элементом строки (кроме последнего), но я не могу понять, как заставить программу «знать», что последний элемент является последним элементом,

Вот мой код, как он есть сейчас:

let rec join (separator: string) (l : string list) : string = 
 begin match l with
    | []->""
    | head::head2::list-> if head2=[] then head^(join separator list) else head^separator^(join separator list)
 end


let test () : bool =
 (join "," ["a";"b";"c"]) = "a,b,c"
;; run_test "test_join1" test 

Заранее спасибо!

Ответы [ 2 ]

9 голосов
/ 21 января 2012

Ты почти у цели. Идея состоит в том, чтобы разбить список в трех случаях, когда он содержит 0, 1 или как минимум 2 элемента. Если в списке более одного элемента, вы можете вставить separator в строку вывода:

let rec join (separator: string) (l : string list) : string =   
   begin match l with
    | [] -> ""
    | head::[] -> head
    | head::list-> head^separator^(join separator list)  
   end

У меня есть несколько комментариев о вашей функции:

  • Тип аннотации избыточен. Поскольку (^) является оператором конкатенации строк, средство проверки типов может легко определять типы separator, l и вывод функции.
  • Нет необходимости использовать begin/and пару. Поскольку у вас есть только один уровень сопоставления с образцом, компилятору нет путаницы.
  • Вы можете использовать function для устранения match l with части.

Следовательно, ваш код может быть сокращен до:

let rec join sep l = 
    match l with
    | [] -> ""
    | x::[] -> x
    | x::xs -> x ^ sep ^ join sep xs

или даже более кратко:

 let rec join sep = function
    | [] -> ""
    | x::[] -> x
    | x::xs -> x ^ sep ^ join sep xs 
7 голосов
/ 21 января 2012

Пустой список - [], список с одним элементом - [h], а список хотя бы с одним элементом - h::t. Таким образом, ваша функция может быть записана как:

let rec join separator = function
  | []   -> ""
  | [h]  -> h
  | h::t -> h ^ separator ^ join separator t
...