metaparse の meta_hs を使って C++ で Haskell を書く

と、いうことで C++なうで注目を浴び、巷で話題沸騰中の metaparse で Haskell を書いてみました。
まぁ Haskell はあんまり書けないんですけどね!

[ソース]

#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 を付けるとエラーになりました。

[コンパイラ]

  • g++ (GCC) 4.8.0 20120415 (experimental)
  • clang++ (LLVM) 3.2 20120514(trunk)