Evil ML: ML to C++ template language
MLからC++テンプレートメタコードへのコンパイラーが公開されている。
以下のMLにおけるクイックソートが、
(* Example: quick sort *)
type 'a list = [] | :: of 'a * 'a list
let rec foldr f xs acc = match xs with
| [] -> acc
| x :: xs -> f x (foldr f xs acc)
let length xs = foldr (fun _ acc -> acc + 1) xs 0
let append xs ys = foldr (fun y acc -> y :: acc) xs ys
let filter f xs = foldr (fun x acc -> if f x then x :: acc else acc) xs []
let rec qsort xs = match xs with
| [] -> []
| [x] -> [x]
| pivot :: rest ->
let ys = qsort (filter (fun x -> x < pivot) rest) in
let zs = qsort (filter (fun x -> x >= pivot) rest) in
append ys (pivot :: zs)
let rec nth i xs = match xs with
| [] -> error
| x :: xs -> if i = 0 then x else nth (i-1) xs
let l1 = [5; 4; 8; 1; 6; 3; 7; 2]
let l2 = qsort l1
let x0 = nth 0 l2
let x1 = nth 1 l2
let x2 = nth 2 l2
let x3 = nth 3 l2
let x4 = nth 4 l2
let x5 = nth 5 l2
let x6 = nth 6 l2
let x7 = nth 7 l2
(*!
// This is C++ code.
#include <cstdio>
int main () { // We use printf in order to output readable assembly code.
std::printf("%d ", x0::val);
std::printf("%d ", x1::val);
std::printf("%d ", x2::val);
std::printf("%d ", x3::val);
std::printf("%d ", x4::val);
std::printf("%d ", x5::val);
std::printf("%d ", x6::val);
std::printf("%d\n", x7::val);
return 0;
}
*)
以下のような素敵なC++テンプレートメタコードに変換される。
#include "evilml.hpp"
struct __ml_nil {
static const int tag = 1000123519;
};
template <class x0, class x1>
struct __ml_cons {
static const int tag = 478463344;
typedef x0 fst;
typedef x1 snd;
};
struct foldr {
template <class f, class xs, class acc>
class fun {
private:
struct __then2 {
template <class>
struct fun {
static const int tag = 0;
typedef acc type;
};
};
struct __else2 {
template <class>
class fun {
private:
struct __then1 {
template <class>
class fun {
private:
typedef typename xs::fst x;
typedef typename xs::snd xs1;
public:
static const int tag = 0;
typedef typename
f::template fun
<x, typename foldr::template fun<f, xs1, acc>::type>::type type;
};
};
struct __else1 {
template <class>
struct fun {
static const int tag = 0;
typedef void type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 478463344), __then1, __else1>::type::
template fun<void>::type type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 1000123519), __then2, __else2>::type::template fun
<void>::type type;
};
};
struct length {
template <class xs>
class fun {
private:
struct __fun1 {
template <class, class acc>
struct fun {
static const int tag = 0;
typedef __ml_int<(acc::val + 1)> type;
};
};
public:
static const int tag = 0;
typedef typename
foldr::template fun<__fun1, xs, __ml_int<0> >::type type;
};
};
struct append {
template <class xs, class ys>
class fun {
private:
struct __fun2 {
template <class y, class acc>
struct fun {
static const int tag = 0;
typedef __ml_cons<y, acc> type;
};
};
public:
static const int tag = 0;
typedef typename foldr::template fun<__fun2, xs, ys>::type type;
};
};
struct filter {
template <class f, class xs>
class fun {
private:
struct __fun3 {
template <class x, class acc>
class fun {
private:
struct __then3 {
template <class>
struct fun {
static const int tag = 0;
typedef __ml_cons<x, acc> type;
};
};
struct __else3 {
template <class>
struct fun {
static const int tag = 0;
typedef acc type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<f::template fun<x>::type::val, __then3, __else3>::type::
template fun<void>::type type;
};
};
public:
static const int tag = 0;
typedef typename foldr::template fun<__fun3, xs, __ml_nil>::type type;
};
};
struct qsort {
template <class xs>
class fun {
private:
struct __then8 {
template <class>
struct fun {
static const int tag = 0;
typedef __ml_nil type;
};
};
struct __else8 {
template <class>
class fun {
private:
struct __then7 {
template <class>
class fun {
private:
typedef typename
xs::fst x;
struct __then6 {
template <class>
struct fun {
static const int tag = 0;
typedef __ml_cons<x, __ml_nil> type;
};
};
struct __else6 {
template <class>
class fun {
private:
struct __then5 {
template <class>
class fun {
private:
typedef typename xs::fst pivot;
typedef typename
xs::snd rest;
struct __fun4 {
template <class x>
struct fun {
static const int tag = 0;
typedef __ml_bool<__ml_lt<x, pivot>::val> type;
};
};
typedef typename
qsort::template fun
<typename filter::template fun<__fun4, rest>::type>::
type ys;
struct __fun5 {
template <class x8>
struct fun {
static const int tag = 0;
typedef __ml_bool<__ml_ge<x8, pivot>::val> type;
};
};
typedef typename
qsort::template fun
<typename filter::template fun<__fun5, rest>::type>::
type zs;
public:
static const int tag = 0;
typedef typename
append::template fun<ys, __ml_cons<pivot, zs> >::type type;
};
};
struct __else5 {
template <class>
struct fun {
static const int tag = 0;
typedef void type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 478463344), __then5, __else5>::type::
template fun<void>::type type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::snd::tag == 1000123519), __then6, __else6>::type::
template fun<void>::type type;
};
};
struct __else7 {
template <class>
class fun {
private:
struct __then4 {
template <class>
class fun {
private:
typedef typename xs::fst pivot;
typedef typename
xs::snd rest;
struct __fun6 {
template <class x9>
struct fun {
static const int tag = 0;
typedef __ml_bool<__ml_lt<x9, pivot>::val> type;
};
};
typedef typename
qsort::template fun
<typename filter::template fun<__fun6, rest>::type>::type ys;
struct __fun7 {
template <class x10>
struct fun {
static const int tag = 0;
typedef __ml_bool<__ml_ge<x10, pivot>::val> type;
};
};
typedef typename
qsort::template fun
<typename filter::template fun<__fun7, rest>::type>::type zs;
public:
static const int tag = 0;
typedef typename
append::template fun<ys, __ml_cons<pivot, zs> >::type type;
};
};
struct __else4 {
template <class>
struct fun {
static const int tag = 0;
typedef void type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 478463344), __then4, __else4>::type::
template fun<void>::type type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 478463344), __then7, __else7>::type::
template fun<void>::type type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 1000123519), __then8, __else8>::type::template fun
<void>::type type;
};
};
struct nth {
template <class i, class xs>
class fun {
private:
struct __then11 {
template <class>
struct fun {
static const int tag = 0;
typedef void type;
};
};
struct __else11 {
template <class>
class fun {
private:
struct __then10 {
template <class>
class fun {
private:
typedef typename xs::fst x;
typedef typename
xs::snd xs1;
struct __then9 {
template <class>
struct fun {
static const int tag = 0;
typedef x type;
};
};
struct __else9 {
template <class>
struct fun {
static const int tag = 0;
typedef typename
nth::template fun<__ml_int<(i::val - 1)>, xs1>::type type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(i::val == 0), __then9, __else9>::type::template fun
<void>::type type;
};
};
struct __else10 {
template <class>
struct fun {
static const int tag = 0;
typedef void type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 478463344), __then10, __else10>::type::
template fun<void>::type type;
};
};
public:
static const int tag = 0;
typedef typename
__ml_if<(xs::tag == 1000123519), __then11, __else11>::type::
template fun<void>::type type;
};
};
typedef __ml_cons
<__ml_int<5>, __ml_cons
<__ml_int<4>, __ml_cons
<__ml_int<8>, __ml_cons
<__ml_int<1>, __ml_cons
<__ml_int<6>, __ml_cons
<__ml_int<3>, __ml_cons
<__ml_int<7>, __ml_cons<__ml_int<2>, __ml_nil> > > > > > > > l1;
typedef qsort::fun<l1>::type l2;
typedef nth::fun<__ml_int<0>, l2>::type x0;
typedef nth::fun<__ml_int<1>, l2>::type x1;
typedef nth::fun<__ml_int<2>, l2>::type x2;
typedef nth::fun<__ml_int<3>, l2>::type x3;
typedef nth::fun<__ml_int<4>, l2>::type x4;
typedef nth::fun<__ml_int<5>, l2>::type x5;
typedef nth::fun<__ml_int<6>, l2>::type x6;
typedef nth::fun<__ml_int<7>, l2>::
type x7;
// This is C++ code.
#include <cstdio>
int main () { // We use printf in order to output readable assembly code.
std::printf("%d ", x0::val);
std::printf("%d ", x1::val);
std::printf("%d ", x2::val);
std::printf("%d ", x3::val);
std::printf("%d ", x4::val);
std::printf("%d ", x5::val);
std::printf("%d ", x6::val);
std::printf("%d\n", x7::val);
return 0;
}
ドワンゴ広告
この記事はドワンゴ勤務中に見つけたのでメモ代わりに書いた。
ドワンゴ社内に関数型プログラマーが何人いるかは把握していない。
ドワンゴは本物のC++プログラマーを募集しています。
CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0
作ったことは称賛する。するが……。よめねーようわわわーん。Orz
ReplyDelete