Skip to content

Commit 24ec5a6

Browse files
committed
---
yaml --- r: 14836 b: refs/heads/try c: 7c70d35 h: refs/heads/master v: v3
1 parent 63d9232 commit 24ec5a6

File tree

4 files changed

+370
-263
lines changed

4 files changed

+370
-263
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: 9086c6f5a2ac3e09c358d05700bfbcb18378bdf6
5+
refs/heads/try: 7c70d35a10d7157b4a31ac1db18afe96268735f6
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/libcore/result.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,86 @@ fn chain<T, U: copy, V: copy>(res: result<T, V>, op: fn(T) -> result<U, V>)
8989
}
9090
}
9191

92+
// ______________________________________________________________________
93+
// Note:
94+
//
95+
// These helper functions are written in a "pre-chained" (a.k.a,
96+
// deforested) style because I have found that, in practice, this is
97+
// the most concise way to do things. That means that they do not not
98+
// terminate with a call to `ok(v)` but rather `nxt(v)`. If you would
99+
// like to just get the result, just pass in `ok` as `nxt`.
100+
101+
#[doc = "
102+
Maps each element in the vector `ts` using the operation `op`. Should an
103+
error occur, no further mappings are performed and the error is returned.
104+
Should no error occur, a vector containing the result of each map is
105+
passed to the `nxt` function.
106+
107+
Here is an example which increments every integer in a vector,
108+
checking for overflow:
109+
110+
fn inc_conditionally(x: uint) -> result<uint,str> {
111+
if x == uint::max_value { ret err(\"overflow\"); }
112+
else { ret ok(x+1u); }
113+
}
114+
map([1u, 2u, 3u], inc_conditionally) {|incd|
115+
assert incd == [2u, 3u, 4u];
116+
}
117+
118+
Note: if you have to combine a deforested style transform with map,
119+
you should use `ok` for the `nxt` operation, as shown here (this is an
120+
alternate version of the previous example where the
121+
`inc_conditionally()` routine is deforested):
122+
123+
fn inc_conditionally<T>(x: uint,
124+
nxt: fn(uint) -> result<T,str>) -> result<T,str> {
125+
if x == uint::max_value { ret err(\"overflow\"); }
126+
else { ret nxt(x+1u); }
127+
}
128+
map([1u, 2u, 3u], inc_conditionally(_, ok)) {|incd|
129+
assert incd == [2u, 3u, 4u];
130+
}
131+
"]
132+
fn map<T,U:copy,V:copy,W>(ts: [T],
133+
op: fn(T) -> result<V,U>,
134+
nxt: fn([V]) -> result<W,U>) -> result<W,U> {
135+
let mut vs: [V] = [];
136+
vec::reserve(vs, vec::len(ts));
137+
for t in ts {
138+
alt op(t) {
139+
ok(v) { vs += [v]; }
140+
err(u) { ret err(u); }
141+
}
142+
}
143+
ret nxt(vs);
144+
}
145+
146+
#[doc = "Same as map, but it operates over two parallel vectors.
147+
148+
A precondition is used here to ensure that the vectors are the same
149+
length. While we do not often use preconditions in the standard
150+
library, a precondition is used here because result::t is generally
151+
used in 'careful' code contexts where it is both appropriate and easy
152+
to accommodate an error like the vectors being of different lengths."]
153+
fn map2<S,T,U:copy,V:copy,W>(ss: [S], ts: [T],
154+
op: fn(S,T) -> result<V,U>,
155+
nxt: fn([V]) -> result<W,U>)
156+
: vec::same_length(ss, ts)
157+
-> result<W,U> {
158+
let n = vec::len(ts);
159+
let mut vs = [];
160+
vec::reserve(vs, n);
161+
let mut i = 0u;
162+
while i < n {
163+
alt op(ss[i],ts[i]) {
164+
ok(v) { vs += [v]; }
165+
err(u) { ret err(u); }
166+
}
167+
i += 1u;
168+
}
169+
ret nxt(vs);
170+
}
171+
92172
#[cfg(test)]
93173
mod tests {
94174
fn op1() -> result::result<int, str> { result::ok(666) }

0 commit comments

Comments
 (0)