在C ++ 17 std::optional
中,我对这个决定感到高兴,直到我看到ref。我知道来自Scala,Haskell和Java 8的Optional
/ Maybe
,其中可选的是monad并遵循monadic定律。在C ++ 17实现中不是这种情况。如何使用std::optional
,map
和flatMap
/ bind
这样的函数,我应该如何使用std::optional
vs来获得优势,例如返回{{1}如果它无法计算结果,或者来自函数的-1
?
对我来说更重要的是,为什么nullptr
没有设计为monad,有原因吗?
答案 0 :(得分:4)
Haskell中的我应该如何使用std :: optional,像map和flatMap / bind
这样的函数
Maybe
在没有fmap
的情况下完全可用,它表示可能存在或不存在的值。它还为类型系统带来了区别,因此您需要处理这两种情况。
使用std :: optional vs的优点是什么,例如返回-1,或者如果无法计算结果,则从函数中获取nullptr?
您如何知道错误情况是什么?是0
,-1
,MAX_INT
,nullptr
还是其他什么?如果我同时拥有unsigned int
和int
返回值以及之前返回的int
版本-1
,您应该将它们更改为MAX_INT
或让它们返回不同的值? std::optional
避免了这个问题。
对我来说更重要的是,为什么没有std :: optional设计成monad,有原因吗?
C ++目前是否有monad?除了与容器之外的抽象不同之外,实际上还没有一种方法可以添加该功能。
答案 1 :(得分:4)
提出了P0798r0提案,以及相关的实施here on Github。该提案还涉及一般的monadic接口提议,以及类似可用的std :: expected。这些也可以实现。
答案 2 :(得分:2)
你可以定义bind
和return
超过std::optional
,因此从这个意义上说它仍然是Monad。
例如,可能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>{};
}
实际上定义它可能很有用。
至于为什么标准库没有附带这个或类似的东西,我认为答案是该语言中首选的样式之一。