Skip to content

Commit bc87e66

Browse files
committed
Add option::while_some; also add more pure (close #2927)
1 parent 85e79a3 commit bc87e66

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

src/libcore/option.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ pure fn chain<T, U>(opt: option<T>, f: fn(T) -> option<U>) -> option<U> {
5252
alt opt { some(x) { f(x) } none { none } }
5353
}
5454

55+
#[inline(always)]
56+
pure fn while_some<T>(+x: option<T>, blk: fn(+T) -> option<T>) {
57+
//! Applies a function zero or more times until the result is none.
58+
59+
let mut opt <- x;
60+
while opt.is_some() {
61+
opt = blk(unwrap(opt));
62+
}
63+
}
64+
5565
pure fn is_none<T>(opt: option<T>) -> bool {
5666
//! Returns true if the option equals `none`
5767
@@ -106,18 +116,18 @@ impl extensions<T> for option<T> {
106116
* Update an optional value by optionally running its content through a
107117
* function that returns an option.
108118
*/
109-
fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) }
119+
pure fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) }
110120
/// Applies a function to the contained value or returns a default
111-
fn map_default<U: copy>(def: U, f: fn(T) -> U) -> U
121+
pure fn map_default<U: copy>(def: U, f: fn(T) -> U) -> U
112122
{ map_default(self, def, f) }
113123
/// Performs an operation on the contained value or does nothing
114-
fn iter(f: fn(T)) { iter(self, f) }
124+
pure fn iter(f: fn(T)) { iter(self, f) }
115125
/// Returns true if the option equals `none`
116-
fn is_none() -> bool { is_none(self) }
126+
pure fn is_none() -> bool { is_none(self) }
117127
/// Returns true if the option contains some value
118-
fn is_some() -> bool { is_some(self) }
128+
pure fn is_some() -> bool { is_some(self) }
119129
/// Maps a `some` value from one type to another
120-
fn map<U:copy>(f: fn(T) -> U) -> option<U> { map(self, f) }
130+
pure fn map<U:copy>(f: fn(T) -> U) -> option<U> { map(self, f) }
121131
}
122132

123133
impl extensions<T: copy> for option<T> {
@@ -128,8 +138,8 @@ impl extensions<T: copy> for option<T> {
128138
*
129139
* Fails if the value equals `none`
130140
*/
131-
fn get() -> T { get(self) }
132-
fn get_default(def: T) -> T { get_default(self, def) }
141+
pure fn get() -> T { get(self) }
142+
pure fn get_default(def: T) -> T { get_default(self, def) }
133143
/**
134144
* Gets the value out of an option, printing a specified message on
135145
* failure
@@ -139,6 +149,8 @@ impl extensions<T: copy> for option<T> {
139149
* Fails if the value equals `none`
140150
*/
141151
pure fn expect(reason: ~str) -> T { expect(self, reason) }
152+
/// Applies a function zero or more times until the result is none.
153+
pure fn while_some(blk: fn(+T) -> option<T>) { while_some(self, blk) }
142154
}
143155

144156
#[test]
@@ -177,6 +189,20 @@ fn test_unwrap_resource() {
177189
assert *i == 1;
178190
}
179191

192+
#[test]
193+
fn test_option_while_some() {
194+
let mut i = 0;
195+
do some(10).while_some |j| {
196+
i += 1;
197+
if (j > 0) {
198+
some(j-1)
199+
} else {
200+
none
201+
}
202+
}
203+
assert i == 11;
204+
}
205+
180206
// Local Variables:
181207
// mode: rust;
182208
// fill-column: 78;

0 commit comments

Comments
 (0)