En la el post anterior vimos cómo transform, and_then y or_else permiten escribir código más expresivo con std::optional y std::expected.
Ahora vamos a ir un paso más allá: cómo componer funciones monádicas y diseñar código fluido sin excepciones.
El poder real de los métodos monádicos aparece cuando se encadenan varias transformaciones.
Veamos un ejemplo usando std::optional:
auto half = [](int x) -> std::optional<int> {
return x % 2 == 0 ? x / 2 : std::nullopt;
};
auto addTen = [](int x) { return x + 10; };
std::optional<int> result =
std::optional(8)
.and_then(half)
.transform(addTen); // ((8 / 2) + 10) = 14
Si en algún punto se devuelve std::nullopt, toda la cadena se corta automáticamente.
Con std::expected, el patrón es el mismo, pero ahora los errores son valores explícitos:
std::expected<int, std::string> parse(std::string s);
std::expected<int, std::string> divideByTwo(int x);
auto r = parse("42")
.and_then(divideByTwo)
.transform([](int n){ return n * 3; })
.or_else([](auto err){
std::cerr << "Error: " << err << "\\n";
return std::expected<int, std::string>(0);
});
Si cualquiera de las funciones falla, se propaga el error automáticamente.
No se necesitan try/catch ni comprobaciones manuales.
Si querés que tus funciones participen en estos encadenamientos, deben:
- Retornar un std::optional<T> o std::expected<T, E>.
- No lanzar excepciones.
- No asumir que el valor siempre existe.
Ejemplo:
std::expected<int, std::string> toInt(std::string s) {
try {
return std::stoi(s);
} catch (...) {
return std::unexpected("invalid integer");
}
}
Esta función ya puede encadenarse con .and_then() o .transform().
Los métodos monádicos de C++23 no solo son una mejora sintáctica, son una nueva forma de estructurar la lógica — más declarativa, más segura y más fácil de leer.
Y recuerda:
- Usá transform para funciones simples (no cambian el contexto).
- Usá and_then cuando la función devuelva otro optional o expected.
- Usá or_else para recuperación o logging.
- Evitá mezclar estos métodos con if/else sobre .has_value() — se pierde la gracia funcional.
- Pensá tus funciones como operaciones puras.
