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.
I can take a look at it tonight, thanks for the reproduction!
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