I talked about it on #rust-beginners
, and I was suggested to share this problem.
In OCaml you can easily do:
let min_rat pr = match pr with
((_,0),p2) -> p2
| (p1,(_,0)) -> p1
| (((n1,d1) as r1), ((n2,d2) as r2)) ->
if (n1 * d2 ) < (n2 * d1) then r1 else r2;;
Trying to do the same in Rust results in an error:
fn min_rat(x: (i32, i32), y: (i32, i32)) -> (i32, i32) {
match (x, y) {
((_, 0), p2) => p2,
(p1, (_, 0)) => p1,
(r1 @ (n1, d1), r2 @ (n2, d2)) => if n1 * d2 < n2 * d1 {r1} else {r2},
}
}
gives
pattern bindings are not allowed after an `@`
(playground: https://play.rust-lang.org/?gist=61dbad9ba71473e407864e3536ec7b5d&version=stable)
Currently, the only way to implement this is to duplicate the matched part in the following way:
((n1, d1), (n2, d2)) => if n1 * d2 < n2 * d1 {(n1, d1)} else {(n2, d2)},
This is error-prone (you can easily forget to change the returned value while changing the match condition) and superfluous. Is there any reason why an extra name binding is not allowed here? It’s all read-only.