[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にどっぷり浸かろう。
これはいい言語かも。