Вложенные монадические операции создают нечитаемый код.C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Вложенные монадические операции создают нечитаемый код.

Сообщение Anonymous »

Мне нужна помощь в написании читаемого кода для составления монадических обратных вызовов C++23. Я обнаружил, что, хотя код, который я создаю, имеет тенденцию быть более правильным, сценарии, в которых мне нужно объединить результаты двух вычислений, создают код, который значительно менее читаем, чем стандартный способ выполнения задач.
Возьмем пример с дополнительными функциями с ограничением, что foo() должен вызываться перед bar(): в качестве мотивирующего примера предположим, что мы пишем синтаксический анализатор и оба foo и bar потребляют некоторый токен из наш список токенов для анализа.
std::optional foo();
std::optional bar();

И умножить их результаты, если они существуют, или распространить nullopt в противном случае
"Обычный способ" сделать это
std::optional baz() {
std::optional maybe_foo = foo();
if(!maybe_foo.has_value()) {
return std::nullopt;
}
std::optional maybe_bar = bar();
if(!maybe_bar.has_value()) {
return std::nullopt;
}
return maybe_foo.value() * maybe_bar.value();
}

Монадический подход:
std::optional baz() {
return foo().and_then([](int foo_res) {
return bar().and_then([foo_res](int bar_res) {
return foo_res * bar_res;
});
});
}

И эта вложенность меня очень беспокоит. Я обнаружил, что в более сложных вычислениях ситуация становится еще хуже, когда эта растущая пирамида логики вырастает из моих функций, поскольку мы никогда не сможем замкнуть нашу логику.
Что я делаю не так?
В качестве более наглядного примера ниже приведена функция из написанного мною парсера, которую я считаю особенно нечитаемой. Функциональность функции менее важна, чем описанная выше пирамида обратных вызовов...
template
Parser::maybe_expression Parser::assignment() {
// Given an arbitrary expression, return the VariableExpression contained within
// if one exists, otherwise return a nullopt
auto try_extract_variable = [](grammar::Expression expr)
-> std::optional {
return try_get(std::move(expr))
.and_then([](grammar::PrimaryExpression primary_expr) -> std::optional {
return try_get(std::move(primary_expr.data));
});
};
return equality()
.and_then([&](std::unique_ptr expr) {
// If the top token after parsing Equality() is an =, we either return an
// assignment expression or an error. Otherwise, we directly return the Equality() expression
return consume()
.transform([&](const token::Equal &equal) {
// We are parsing an assignment expression, and so we would like to extract the
// Variable that we are to assign, otherwise return an error.
return try_extract_variable(std::move(*expr))
.transform([&](const grammar::VariableExpression &variable) -> maybe_expression {
return expression()
.map([&](std::unique_ptr assign_to) {
return std::make_unique(grammar::AssignmentExpression{
variable, std::move(assign_to), variable.line_number
});
});
})
.value_or(tl::unexpected{Error{equal.line_number,
ErrorType::kBadAssign,
fmt::format("Incomplete assignment expression")
}});
})
.or_else([&] -> std::optional {
return std::move(expr);
})
.value();
});
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... dable-code
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Вложенные монадические операции создают нечитаемый код.
    Anonymous » » в форуме C++
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Вложенные монадические операции создают нечитаемый код.
    Anonymous » » в форуме C++
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Вложенные монадические операции создают нечитаемый код.
    Anonymous » » в форуме C++
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • VS код текст вывод нечитаемый формат в новом окне
    Anonymous » » в форуме Python
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Запись нулевых значений в файл паркета с помощью Parquet.Net создает нечитаемый файл паркета.
    Anonymous » » в форуме C#
    0 Ответы
    68 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»