boost::optionalを使ってみて 第2回
前回よりはだいぶまし
val hoge = Some(10).map{(x)=> x +1 };
これをC++に導入する
twitterでコメントいただいて,引数の型を明示的にspecifyするのは行けてない,とのことでした.折を見て修正しようと思います
boost::optionalを使ってみて 第2回
boost::optionalをやってみました.C++でOption型を実現する例のアレ.
OptionがNoneでなかったら,プロシージャを継続するというアレ.
C++でも専用の関数を利用すれば,ある程度フレキシブルに利用できることが確認できた.
つまり,scala入門時によく言われる,Option型でmapして,その中のプロシージャがモナドを部分的に満たすアレをC++で実装する.
scala> val hage = Some(10) hage: Some[Int] = Some(10) scala> val result = hage.map{ (x) => | println(x+1) | } 11 result: Option[Unit] = Some(())
使い方
boost::optional<int> aaa = 10; auto result = KOKUU2::Match::eval( aaa, //マップを開始したいoptional変数 [](int i){return i*i;}, //マップの中で処理する内容 new double); //戻り値として期待する型 std::cout << "result:" << *result << std::endl;
虚空2の設計
- Optionに関するmapに対応する処理をC++でも行い安くする.
- 利用者側からはifを使わなくてもいいというメリットを与える.
- 引数とするlambdaはモナド則をできるだけ満たすように書かなければいけなくなるので,コードが関数型っぽく矯正できる(if文で切った中に長いプロシージャを書かれて辟易したことがあった)
#include<boost/optional.hpp> namespace KOKUU2{ namespace Match{ template<class T, class lambda, class OUT>//lambdaをキャプチャして変数をbind boost::optional<OUT> eval(boost::optional<T> x, lambda functor, OUT* out){ delete out; if(x){ auto res = static_cast<OUT>(std::bind(functor, x.get())()); //bindで目標のプロシージャを作る return boost::optional<OUT>(res); }; return boost::none; }; }}//endnamepace