2012-01-21 41 views
8

我是OCaml的新手(並且在學習編程方面一般還是新手),並且我有一個關於檢查字符串列表中下一個元素是什麼類型的字符串的快速問題。如何檢查OCaml中的下一個'head'是否爲空?

我想要它在字符串的每個元素(除了最後一個)之間放置一個分隔符,但我無法弄清楚如何讓程序「知道」最後一個元素是最後一個元素。

這裏是我的代碼,因爲它現在是:提前

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 

謝謝!

回答

9

你快到了。這個想法是在三種情況下將它分爲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

的空單是[],列表中的一個元素是[h]和列表至少有一個元素是h::t。所以你的功能可以寫成:

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