diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-17 13:54:24 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-17 13:57:36 -0400 |
| commit | bc87e66355e658cffb84396d1783364e23ddc6d2 (patch) | |
| tree | ccc465bac6152c6dd04d666d60d0fea100a88021 | |
| parent | 85e79a3a8a52e339040a8533ba272a5891a62ce5 (diff) | |
| download | rust-bc87e66355e658cffb84396d1783364e23ddc6d2.tar.gz rust-bc87e66355e658cffb84396d1783364e23ddc6d2.zip | |
Add option::while_some; also add more pure (close #2927)
| -rw-r--r-- | src/libcore/option.rs | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 80b3915cb90..dabfa04ef24 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -52,6 +52,16 @@ pure fn chain<T, U>(opt: option<T>, f: fn(T) -> option<U>) -> option<U> { alt opt { some(x) { f(x) } none { none } } } +#[inline(always)] +pure fn while_some<T>(+x: option<T>, blk: fn(+T) -> option<T>) { + //! Applies a function zero or more times until the result is none. + + let mut opt <- x; + while opt.is_some() { + opt = blk(unwrap(opt)); + } +} + pure fn is_none<T>(opt: option<T>) -> bool { //! Returns true if the option equals `none` @@ -106,18 +116,18 @@ impl extensions<T> for option<T> { * Update an optional value by optionally running its content through a * function that returns an option. */ - fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) } + pure fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) } /// Applies a function to the contained value or returns a default - fn map_default<U: copy>(def: U, f: fn(T) -> U) -> U + pure fn map_default<U: copy>(def: U, f: fn(T) -> U) -> U { map_default(self, def, f) } /// Performs an operation on the contained value or does nothing - fn iter(f: fn(T)) { iter(self, f) } + pure fn iter(f: fn(T)) { iter(self, f) } /// Returns true if the option equals `none` - fn is_none() -> bool { is_none(self) } + pure fn is_none() -> bool { is_none(self) } /// Returns true if the option contains some value - fn is_some() -> bool { is_some(self) } + pure fn is_some() -> bool { is_some(self) } /// Maps a `some` value from one type to another - fn map<U:copy>(f: fn(T) -> U) -> option<U> { map(self, f) } + pure fn map<U:copy>(f: fn(T) -> U) -> option<U> { map(self, f) } } impl extensions<T: copy> for option<T> { @@ -128,8 +138,8 @@ impl extensions<T: copy> for option<T> { * * Fails if the value equals `none` */ - fn get() -> T { get(self) } - fn get_default(def: T) -> T { get_default(self, def) } + pure fn get() -> T { get(self) } + pure fn get_default(def: T) -> T { get_default(self, def) } /** * Gets the value out of an option, printing a specified message on * failure @@ -139,6 +149,8 @@ impl extensions<T: copy> for option<T> { * Fails if the value equals `none` */ pure fn expect(reason: ~str) -> T { expect(self, reason) } + /// Applies a function zero or more times until the result is none. + pure fn while_some(blk: fn(+T) -> option<T>) { while_some(self, blk) } } #[test] @@ -177,6 +189,20 @@ fn test_unwrap_resource() { assert *i == 1; } +#[test] +fn test_option_while_some() { + let mut i = 0; + do some(10).while_some |j| { + i += 1; + if (j > 0) { + some(j-1) + } else { + none + } + } + assert i == 11; +} + // Local Variables: // mode: rust; // fill-column: 78; |
