Hey Roc friends,
I've been doing some railway-oriented error handling and wanted to chain a few Try-returning steps in a pipeline, something like this:
Chain := {}.{
and_then : Try(a, e), (a -> Try(b, e)) -> Try(b, e)
and_then = |result, next|
match result {
Ok(value) => next(value)
Err(e) => Err(e)
}
}
expect Chain.and_then(Ok(2.U64), |x| Ok(x + 1)) == Ok(3.U64)
expect Chain.and_then(Err("short-circuit"), |x| Ok(x + 1.U64)) == Err("short-circuit")
Any plans to add something like this to complement ?? Or does it already exist in some other form and I've simply overlooked it?
Thanks! :slight_smile:
For something like this, I would use the ? operator:
f = |n| if n == 1 Ok(2.U64) else Err("short-circuit")
g = |n| {
v = f(n)? + 1
Ok(v)
}
But I think the gap is that ? forces early return, where you might instead want to chain two or more and_thens and use their result. I'm not sure of the reason to exclude and_then but include map_ok etc.
Yes, that's how I feel too – including map_ok but not and_then feels kind of inconsistent.
To make it concrete, here are two little steps that can each fail (f is @Aurélien Geron 's, g is a second one):
f = |n| if n == 1 { Ok(2.U64) } else { Err("short-circuit") }
g = |n| if n == 2 { Ok("made it!") } else { Err("no match") }
With and_then, chaining them is just an expression – I can assign it, pass it on, whatever:
result = f(1) -> and_then(g) # Ok("made it!")
With ? I get the same result, but it has to live inside a function that returns Try, because ? exits early:
with_qmark = |n| {
x = f(n)?
g(x)
}
# with_qmark(1) == Ok("made it!")
Both work, but when I just want the chained value inline – not to bail out of the surrounding function – and_then is the natural fit, and ? can't quite reach it, or am I mistaken?
Last updated: Jul 23 2026 at 13:15 UTC