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.
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');;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With