2014-02-08 58 views
0

我使用OCaml中寫一個函數,整數的列表和一個int元素,並返回對的列表,其中每對中的第一個元素是INT元件和該對中的第二個元素是列表中的成員。例如,假設我有數字1和列表[10; 20; 30]作爲輸入。我喜歡函數返回[(1,10); (1,20); (1,30)]。我寫了下面的功能:配對的int與整數的列表OCaml中

let rec f (lst : int list) (elm : int) : (int*int) list = 
    match lst with 
    | [] -> failwith "empty list" 
    | [x] -> [(x, elm)];; 

我收到以下錯誤:

Characters 59-120:                
Warning 8: this pattern-matching is not exhaustive.        
Here is an example of a value that is not matched:        
_::_::_ val f : int list -> int -> (int * int) list = <fun> 

我缺少什麼?

回答

1

這裏是你的代碼

let rec f (lst : int list) (elm : int) : (int*int) list = 
    match lst with 
    | [] -> failwith "empty list" 
    | [x] -> [(x, elm)] 

在你match,你列出了兩個情況:[][x]

你的第一種情況是[],你的意思是empty,沒有問題。

你的第二個案例是[x],你要什麼意思?在OCaml中,這意味着a list with only one element

如果有多個元素的情況如何?

對於任何if elsematch with,您應該包括所有情況。

當你解決這個問題,你很快就會發現你真的錯過了更多的東西在那裏。


下面是正確的代碼:

let rec f e l = 
    match l with 
    | [] -> [] 
    | x::[] -> [(e,x)] 
    | x::tl -> (e,x)::(f e tl) 

注意

  1. 上面的代碼是不是tail-recursive,你通常應該考慮一下吧,我會留給你。
  2. 你不需要;;如果你在文件中編寫你的代碼並編譯文件
  3. 你不需要在大多數情況下聲明類型,這是ocaml最好的東西之一。
+0

謝謝你,我如何才能在有一個以上的元素列表中的元素呢?我知道有像h :: t這樣的東西,但是我沒有成功地使用它。 – user1787222

+0

@ user1787222一次只能獲取列表的頭元素。爲了獲得所有的元素,你需要使用遞歸,並且每次你把頭伸出來。 –

+0

@ user1787222我更新了我的答案。如果您認爲它很好,請將我的答案標記爲正確 –

1

模板圖案相匹配([x])長度爲0([])的列表和長度爲1的。編譯器告訴你列表可能有其他長度,所以你的模式可能是錯誤的(這是真的)。

我可能會注意到,這是不是一個錯誤得到一個空列表作爲參數。用這種方式思考會使問題更難回答。如果你得到一個空的列表,正確的答案是一個空對列表。

1
let rec f e = function 
    | [] -> [] 
    | x::tl -> (e,x)::f e tl 

或者

let f e = List.map (fun x -> (e,x)) 

測試

# f 1 [];; 
- : (int * 'a) list = [] 
# f 1 [10;20;30];; 
- : (int * int) list = [(1, 10); (1, 20); (1, 30)]