Stream: bugs

Topic: Issues Working with Multiple Try Errors


view this post on Zulip Edwin Santos (Dec 02 2025 at 02:17):

Hi, for today's AoC I tried creating the following small function

parse_direction : Str -> Try(I64, [RotationIsNotLR, BadNumStr])
parse_direction = |string| {
    if string.starts_with("L") {
        parse_attempt = string.drop_prefix("L") -> I64.from_str
        l_result = map_ok(parse_attempt, |n| n*-1)?
        Ok(l_result)
    } else if string.starts_with("R") {
        parse_attempt = string.drop_prefix("R") -> I64.from_str
        r_result = parse_attempt?
        Ok(r_result)
    } else {
        Err(RotationIsNotLR)
    }
}

which looks like it should simply propagate the parse errors up to the error set and then keep moving forward. However the compiler actually gives me the following type error:

-- TYPE MISMATCH ---------------------------------

This expression is used in an unexpected way:
     ┌─ aoc_2025_01.roc:4479:20
     │
4479 │         l_result = map_ok(parse_attempt, |n| n*-1)?
     │                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It has the type:
    [Err([BadNumStr])][Ok(I64)]

But I expected it to be:
    Try(I64, [BadNumStr, RotationIsNotLR])

So it seems like ? is having trouble correctly converting the original error to the expanded error set. If resolving this isn't too crazy I can also take a crack at the issue tomorrow.

view this post on Zulip Richard Feldman (Dec 02 2025 at 02:24):

I can take a look at it tonight, thanks for the reproduction!

view this post on Zulip Edwin Santos (Dec 02 2025 at 02:42):

Yup, also uses map_ok (I'll put a PR up once I've finished up snapshot tests):

        map_ok : Try(a, err), (a -> b) -> Try(b, err)
        map_ok = |try, fn| {
            match try {
            Ok(ok_val) => Ok(fn(ok_val))
            Err(e) => Err(e)
            }
        }

Last updated: Dec 21 2025 at 12:15 UTC