Ocaml中的嵌套模式匹配

时间:2013-03-21 09:35:18

标签: pattern-matching ocaml unused-variables

我想在Ocaml中编写一个函数,给出一个四元组列表和一个四元组(x,y,z,f),返回包含元组的列表(x',y',z',g)这样x = x'或y = y'或z = z'(这些是整数)。这是我的第一次尝试

let rec constrained_by c list =
   match s with
   | []-> []
   | hd :: tl ->
 begin
   let Cell(x,y,r,_)=  c in  (*warning*)
   begin
     match hd with 
     | Cell(x,_,_,Some(_))-> hd::constrained_by c tl
     | Cell(_, y, _,Some(_)) -> hd::constrained_by c tl
     | Cell(_, _, r,Some(_)) -> hd::constrained_by c tl
     | _ -> constrained_by c tl
   end 
 end

问题:当它被调用时,无论我们匹配什么四倍,它都会返回原始列表。 此外,问题是返回警告,行(警告)中的x,y,r未使用。

2 个答案:

答案 0 :(得分:7)

正如吉安所说,警卫是解决问题的方法。好消息是代码可以更接近您的书面规范:

let rec constrained_by ((x,y,z,_) as c) list = match list with
   | [] -> []
   | ((x',y',z',_) as c') :: tl when x = x' or y=y' or z=z' ->
       c' :: constrained_by c tl
    | hd :: tl -> constrained_by c tl
;;

微小的测试:

let _ = constrained_by (1,2,3,"foo") [1,0,0,0; 0,2,0,0; 0,0,3,0; 0,0,0,0];;
- : (int * int * int * int) list = [(1, 0, 0, 0); (0, 2, 0, 0); (0, 0, 3, 0)]

请注意,您也可以使用List.filter

let constrained_by (x,y,z,_) = List.filter (fun (x',y',z',_) -> x = x' or y=y' or z=z');;

答案 1 :(得分:4)

我认为你在那里滥用模式匹配。类似Cell(x,_,_,Some(_))的模式将匹配任何内容,因为它是重新绑定x。范围中存在变量x的事实并不意味着它将坚持该元组元素具有与x相同的值。你的三种模式完全等同于它们匹配的结果。

如果你想要完成任务,你可能需要考虑使用警卫。