2014-02-08 33 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)]