Reputation: 251
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.
Upvotes: 4
Views: 4197
Reputation: 4405
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');;
Upvotes: 7
Reputation: 13945
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.
Upvotes: 4