metaparse の meta_hs を使って C++ で Haskell を書く
と、いうことで C++なうで注目を浴び、巷で話題沸騰中の metaparse で Haskell を書いてみました。
まぁ Haskell はあんまり書けないんですけどね!
[metaparse]
[ソース]
#define BOOST_MPL_LIMIT_STRING_SIZE 50 #define MPLLIBS_STRING_MAX_LENGTH BOOST_MPL_LIMIT_STRING_SIZE #include <meta_hs.hpp> #include <double_number.hpp> #include <mpllibs/metaparse/string.hpp> #ifdef _S #error _S already defined #endif #define _S MPLLIBS_STRING typedef meta_hs ::define<_S("plus n m = n + m")>::type ::define<_S( "fact n = " "if n == 0 " "then 1 " "else n * fact(n - 1) " )>::type ::define<_S("fact6 = fact 6")>::type my_haskell; typedef my_haskell::get<_S("plus")> plus; typedef my_haskell::get<_S("fact")> fact; typedef my_haskell::get<_S("fact6")> fact6; #include <boost/mpl/int.hpp> int main(){ using boost::mpl::int_; static_assert(plus::apply<int_<5>>::type::apply<int_<3>>::type::value == 8, ""); static_assert(fact::apply<int_<4>>::type::value == 24, ""); static_assert(fact6::type::value == fact::apply<int_<6>>::type::value, ""); return 0; }
こんな感じで Haskell のコードを C++ コード内に埋め込んで、コンパイル時にパースしています。
実装方法なんかは上記の metaparse.pdf に載っているのでそちらを見てもらえれば分かると思いますが、一言で言ってしまえば
『コンパイル時に文字列から ET に変換を行なっている』
って感じですかね。
Sprout も大概あたまおかしいですが、こっちも別の方向であたまがおかしいですね(褒めてる。
template なので若干評価する時に手間なのが気になりますが、まぁそれぐらいですね。
あ、あと上記のコードは libs/metaparse/example/meta_hs のパスを通さないと動かないので注意。
あと --pedantic を付けるとエラーになりました。