[haXe] haXe、変態的過ぎるの巻
なんじゃあこのswitchはぁぁぁぁぁ!!!!!!! OCamlか!!!!!!
って haXe 自体が OCaml で書かれているし。
w.l.o.g.のこのエントリで紹介されていた論文「Derivation of deterministic inverse programs based on LR parsing」に出ているランレングスのサンプルコードをhaXeで書いてみた。
enum ZeroOrMore { _; cons(f: String, s: ZeroOrMore); } enum Pair { one(f: String); pair(f: String, s: String); } class RunLength { public function new() {} public function deq(param: ZeroOrMore): Pair { return switch (param) { case cons(f, s): switch (s) { case _: pair(f, f); case cons(_f, _s): _s == _ ? (f == _f ? one(f): pair(f, _f)): one(f); }; case _: throw "WTF?"; }; } public function pack(s: ZeroOrMore): ZeroOrMore { return switch (s) { case _: _; case cons(c, r): switch (len(c, 1, r)) { case _: _; case cons(p, l): cons(p, pack(l)); } }; } public function len(c: String, n: Int, s: ZeroOrMore): ZeroOrMore { return switch (s) { case _: cons("<" + c + "," + n + ">", _); case cons(d, r): switch (deq(cons(c, cons(d, _)))) { case one(e): len(e, n + 1, r); case pair(e, f): cons("<" + e + "," + n + ">", cons(f, r)); } } } public function toCons(str: Array<String>): ZeroOrMore { return str.length == 1 ? cons(str[0], _): cons(str.shift(), toCons(str)); } public function fromCons(c: ZeroOrMore): Array<String> { return switch (c) { case _: []; case cons(f, s): [f].concat(fromCons(s)); } } } class Test { public static function main(): Void { var scope = new RunLength(); trace(scope.fromCons(scope.pack(scope.toCons([ "A", "A", "B", "C", "C", "C", "D" ])))); } }
コンパイルと実行:
haxe -main Test -n Test.n Test.hx neko Test.n
出力結果:
Test.hx:70: [<A,2>, <B,1>, <C,3>, <D,1>]
うーん、もうしばらくhaXeにどっぷり浸かろう。
これはいい言語かも。