(首先问题中的“绑定”与无关std::bind
)
我看过Expected<T>的演讲,我认为关于这种技术历史的介绍缺少 Haskell 中这个东西背后的核心思想。
Haskell 的核心思想是你“从不”访问Expected<T>
. 相反,您所做的是将 lambda 传递给Expected<T>
将根据Expected<T>
.
我本来希望这个“绑定”组合器是主要的方法Expected<T>
,所以我不得不问这种编程风格是否由于某种原因被拒绝了。我将then
在下面调用该组合器:
template <class T> class Expected<T> {
....
template <class V, class F> Expected<V> then(F fun_) {
if (!valid()) {
return Expected<V>::fromException(this(??)); // something like that
}
return fun_(get());
}
}
这个组合器的要点是链接一个函数列表,您不需要检查错误,并且第一个失败的函数将使评估短路。
auto res = Expected<Foo>::fromCode([]() { return callFun1(...); })
.then([](Baz& val) { return callFun2(..,val,..); })
.then([](Bar& val) { return callFun3(val,...); });
或者这种语法开始类似于>>=
Haskell 中使用的运算符。
auto res = []() { return callFun1(...); }
>> [](Baz& val) { return callFun2(..,val,..); }
>> [](Bar& val) { return callFun3(val,...); };
callFun1
返回 a Expected<Baz>
,callFun2
返回 a Expected<Bar>
,然后callFun3
返回 a Expected<Foo>
。
如您所见,此代码不检查错误。错误会停止执行,但它们仍然具有Expected<T>
. Either
这是在 Haskell中使用 monad 的标准方式。
正如我所说,肯定有人看过这个。
编辑:我为 callFun{1..3} 编写了错误的返回类型。他们返回Expected<T>
,而不是T
为T
. 这是then
or>>
组合子的全部意义。