plasma.ADTがバージョンアップしました。plasma.ADTの基本についてはこちら
#include<plasma_adt/algebraic_data_type.hpp>
#include<iostream>
#include<boost/optional/optional_io.hpp>
using namespace plasma_adt;
using namespace plasma_adt::place_holder;
using namespace plasma_adt::pattern_match;
struct list :data_type_base<list, void, tuple<int, list>>
{
list(data_type_base const& v) :data_type_base(v) {}
};
const auto Nil = list::instance_function<0>();
const auto Tree = list::instance_function<1>();
int main()
{
auto x = Nil();
auto y = Tree(1, Nil());
auto z = Tree(2, Tree(1, Nil()));
auto f =
memoization_recursion<int, list>()
| Tree(0_, 1_) <= [](auto rec, int x, list next) {std::cout << "Tree:" << x << std::endl; return x + rec(next);}
| Nil <= [](auto) {std::cout << "Nil" << std::endl; return 0;};
std::cout << f(x) << std::endl << std::endl;
std::cout << f(y) << std::endl << std::endl;
std::cout << f(z) << std::endl << std::endl;
auto g=
pattern_match::pattern_match<bool,list>()
| Tree <= []() {return true;}
| Nil <= []() {return false;};
std::cout << g(x) << std::endl;
std::cout << g(y) << std::endl;
std::cout << g(z) << std::endl;
}
git fetchで簡単に引っ張ってこれるようになりました。
またgit cloneしてきたリポジトリにパスを通しておくと上のサンプルのように使えるようになります。
原点回帰というわけでalgebraic_data_type.hppにしました。
一番大きな変更です。継承にすることでIDEの関数引数表示で長ったらしい型を見る必要がなくなりました。
一方で定義が若干面倒になりました。
#define MAKE_PATTERN_TYPE(name, ...)\
struct name :data_type_base<name, __VA_ARGS__>\
{\
name(data_type_base const& v) :data_type_base(v) {}\
};\
こんな感じのマクロを定義しておくと楽ですね。Cプリプロセッサは邪悪らしいので中にはいれてません。
どちらかと言えばC#のFuncに近いですね。順番は違いますが。
上でも言いましたが長ったらしい型名と何故か働かないパラメタヒントから開放されました。
不完全型でも使えるというありがたい仕様と継承ベースにすることでrecursion_tagを使わなくなったことにより使えるようになりました。