auto merge of #5328 : bstrie/rust/optadd, r=graydon

This will allow you to use the `+` operator to add together any two
Options, assuming that the contents of each Option likewise implement
`+`. So Some(4) + Some(1) == Some(5), and adding with None leaves the
other value unchanged.

This might be monoidic? I don't know what that word means!
This commit is contained in:
bors 2013-03-12 00:57:43 -07:00
commit a95b933350
2 changed files with 40 additions and 0 deletions

View File

@ -42,6 +42,7 @@
*/
use cmp::{Eq,Ord};
use ops::Add;
use kinds::Copy;
use util;
use num::Zero;
@ -85,6 +86,18 @@ impl<T:Ord> Ord for Option<T> {
}
}
impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
#[inline(always)]
pure fn add(&self, other: &Option<T>) -> Option<T> {
match (*self, *other) {
(None, None) => None,
(_, None) => *self,
(None, _) => *other,
(Some(ref lhs), Some(ref rhs)) => Some(*lhs + *rhs)
}
}
}
#[inline(always)]
pub pure fn get<T:Copy>(opt: Option<T>) -> T {
/*!

View File

@ -0,0 +1,27 @@
fn main() {
let foo = 1;
let bar = 2;
let foobar = foo + bar;
let nope = optint(0) + optint(0);
let somefoo = optint(foo) + optint(0);
let somebar = optint(bar) + optint(0);
let somefoobar = optint(foo) + optint(bar);
match nope {
None => (),
Some(foo) => fail!(fmt!("expected None, but found %?", foo))
}
fail_unless!(foo == somefoo.get());
fail_unless!(bar == somebar.get());
fail_unless!(foobar == somefoobar.get());
}
fn optint(in: int) -> Option<int> {
if in == 0 {
return None;
}
else {
return Some(in);
}
}