boost::optionalだけじゃなくboost::eitherがほしい

boost::optionalは成功か失敗かしかわからないので
失敗した理由付きのoptionalがほしいよね、という話がTwitterでありました。


Maybeモナド(boost::optional)に対するEitherモナドのように
boost::eitherという名前だと仮定して、こんな感じで使えるといいんじゃないかな、と。

either<int> foo(int a)
{
    typedef either<int> result_type;

    return a >= 0 ?
        a :
        result_type("invalid argument", result_type::error_tag());
}


either<int> x = foo(-1);
if (!x)
    cout << x.what() << endl;

cout << x.get() << endl;

エラーがネストしてた場合なんかは

x.nested().what()

みたいなのも考えたけど空だったときがびみょーなので
ローカルで使える部分特殊化(というか型のパターンマッチ)が言語機能としてほしいなーとか。
(has_nestedみたいなのはあまり書きたくない)


ネストしたエラーのリストとして

for_each(x.nested_errors(), [](either_error e) { cout << e.what() << endl; });

と書ければいいのかな?



あと、エラーを無視させないためにラムダ式を使うとか。

either<int> x(foo(-1), [](either_error e){ cout << e.what() << endl; });

eitherのインタフェースはいろいろ考えないといけないですね。



【参照】
エラー付き戻り値クラステンプレート - にっき(pseudo)
↑throw以外でもエラー内容とりたい。