Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested pattern matching in Ocaml

I want to write a function in Ocaml that given a list of quadruples and a quadruple (x,y,z,f), returns a list of that contains the tuples (x',y',z',g) such that x = x' or y=y' or z = z' (these are integers). Here is my first attempt

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

Problem: When it is called, it returns the original list no matter what quadruple we are matching. Moreover, the problem is it returns warning that x,y, r at line (warning) are unused.

like image 693
Amin Avatar asked Dec 21 '22 08:12

Amin


2 Answers

As said by Gian, guards are a solution to your problem. The good news is that the code can be closer to your written specification:

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
;;

Tiny test:

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)]

Note that you could also use List.filter:

let constrained_by (x,y,z,_) = List.filter (fun (x',y',z',_) -> x = x' or y=y' or z=z');;
like image 56
jrouquie Avatar answered Dec 25 '22 23:12

jrouquie


I think you're misusing pattern matching there. A pattern like Cell(x,_,_,Some(_)) will match anything, as it is rebinding x. The fact that there is a variable x in scope does not mean that it will insist that that tuple element has the same value as x. Your three patterns are entirely equivalent in what they match as a result.

You might need to look into using guards instead if this is how you want to achieve your task.

like image 20
Gian Avatar answered Dec 25 '22 22:12

Gian