функциональное программирование — Как использовать std :: необязательный в переполнении стека

В С ++ 17 std::optional введен, я был рад этому решению, пока я не посмотрел на ссылка. я знаю Optional/Maybe из Scala, Haskell и Java 8, где необязательно является монадой и следует монадическим законам. Это не так в реализации C ++ 17. Как я должен использовать std::optionalбез функций как map а также flatMap/bindВ чем преимущество использования std::optional против возвращения например -1или nullptr из функции, если она не может вычислить результат?
И что более важно для меня, почему не было std::optional предназначен для монады, есть ли причина?

5

Решение

Как я должен использовать std :: необязательно, без функций, таких как map и flatMap / bind

Maybe в Haskell идеально подходит для использования без fmap, это представляет значение, которое может или не может быть там. Это также привносит в систему типов различие, поэтому вам нужно обрабатывать оба случая.

В чем преимущество использования std :: option против, например, возврата -1, или nullptr из функции, если она не может вычислить результат?

Как вы знаете, что такое ошибка? Это 0, -1, MAX_INT, nullptr или что-то другое? Если у меня есть оба unsigned int а также int возвращаемое значение и int версия, ранее возвращенная -1 Вы должны изменить их оба на MAX_INT или заставить их возвращать разные значения? std::optional избегает проблемы.

И что более важно для меня, почему std :: option не предназначен для монады, есть ли причина?

Есть ли в C ++ монады на данный момент? До тех пор, пока абстракция не отличается от контейнерной, на самом деле нет способа добавить эту функциональность.

3

Другие решения

Есть P0798r0 Предложение именно с этим, и связанной с этим реализацией здесь на Github. Предложение также относится к общему предложению монадического интерфейса и аналогично используемому стандарту std :: Ожидается. Реализации тех также доступны.

3

Вы Можно определять bind а также return над std::optionalтак что в этом смысле это все еще монада.

Например, возможный bind

template<typename T1, typename T2>
std::optional<T2> bind(std::optional<T1> a, std::function< std::optional<T2>(T1)> f) {
if(a.has_value()) return f(a.value());
return std::optional<T2>{};
}

На самом деле, вероятно, полезно определить это.

Что касается того, почему стандартная библиотека не поставляется с этим, или что-то вроде этого, я думаю, что ответ — один из предпочтительных стилей в языке.

2
По вопросам рекламы [email protected]