Skip to content

Instantly share code, notes, and snippets.

@plasma-effect
Last active April 4, 2019 12:14
Show Gist options
  • Save plasma-effect/ffc1a66be05eceec1360 to your computer and use it in GitHub Desktop.
Save plasma-effect/ffc1a66be05eceec1360 to your computer and use it in GitHub Desktop.
進化したplasma.ADTとは

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;
}

変更点

管理がgistからgithubになった

git fetchで簡単に引っ張ってこれるようになりました。
またgit cloneしてきたリポジトリにパスを通しておくと上のサンプルのように使えるようになります。

ファイル名がalgebraic_data_type.hppになった

原点回帰というわけでalgebraic_data_type.hppにしました。

型の定義がtypedefから継承になった、定義で使うtupleがstd::tupleからplasma_adt::tupleになった

一番大きな変更です。継承にすることで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に近いですね。順番は違いますが。

VC++インテリセンスでつらい思いをしなくてすむようになった

上でも言いましたが長ったらしい型名と何故か働かないパラメタヒントから開放されました。

標準ライブラリのコンテナクラスを使えるようになった

不完全型でも使えるというありがたい仕様と継承ベースにすることでrecursion_tagを使わなくなったことにより使えるようになりました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment