use with result.try is my favourite bit of Gleam and I'm starting to resent it a little. Every step calls a different module, every module has its own error type, so every line ends up wearing a result.map_error.
pub fn load(id: Int) -> Result(Profile, AppError) {
use row <- result.try(db.fetch(id) |> result.map_error(DbError))
use raw <- result.try(decode(row) |> result.map_error(DecodeError))
use profile <- result.try(validate(raw) |> result.map_error(Invalid))
Ok(profile)
}
Passing constructors as functions keeps it short, sure. But half of each line is now plumbing, and the interesting part, what the step actually does, is squeezed in the middle.
One giant error type that every module imports is not the answer, that's worse. How do you all keep these chains readable? Helpers, a different shape, or just living with it?