Stream: API design

Topic: and_then


view this post on Zulip Johannes Rubenz (Jul 10 2026 at 18:20):

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:

view this post on Zulip Aurélien Geron (Jul 10 2026 at 20:08):

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)
}

view this post on Zulip Jonathan (Jul 10 2026 at 20:20):

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.

view this post on Zulip Johannes Rubenz (Jul 11 2026 at 08:53):

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