次のScalaのケースを考えてみましょう:(このブログ投稿に触発されて)
sealed abstract class Expr
case class X() extends Expr
case class Const(value : Int) extends Expr
case class Add(left : Expr, right : Expr) extends Expr
case class Mult(left : Expr, right : Expr) extends Expr
case class Neg(expr : Expr) extends Expr
Haxeでは、これは次のように応答します。
enum Expr {
X();
Const(val:Int);
Add(left:Expr, right:Expr);
Mult(left:Expr, right:Expr);
Neg(expr:Expr);
}
あらゆる種類のネストされた式のeval関数を作成することは、両方の言語で非常に簡単です。ただし、次の簡略化関数(乗算のみに焦点を当てています)に興味があります。
Scalaの場合:
def simplify(expression: Expr): Expr = expression match {
case Mult(_, Const(0)) => Const(0)
case Mult(Const(0), _) => Const(0)
case Mult(left, Const(1)) => simplify(left)
case Mult(Const(1), right) => simplify(right)
case Mult(Const(leftVal), Const(rightVal)) => Const(leftVal * rightVal)
case Mult(left, right) => Mult(simplify(left),simplify(right))
case Add(left, right) => Add(simplify(left),simplify(right))
case Neg(left) => simplify(left)
case _ => expression
}
私の質問:Haxeで同等のものを書くための最も簡潔でクリーンな方法は何ですか?これらは私の試みですが、どちらにも満足していません。
最初のもの(膨らんだ種類):
public static function simplify(expr:Expr):Expr{
switch(expr){
case Mult(left, right):
if(left.enumEq(Const(0)) || right.enumEq(Const(0))) return Const(0);
switch(left){
case Const(leftVal):
if(leftVal == 1) return right.simplify();
switch(right){
case Const(rightVal): return Const(rightVal * leftVal);
default:
}
default:
switch(right){
case Const(rightVal):
if(rightVal == 1) return left.simplify();
default:
}
}
return Mult(left.simplify(), right.simplify());
case Add(left, right): return Add(left.simplify(), right.simplify());
case Neg(expr): return Neg(expr.simplify());
default: return expr;
}
}
別の試み(より簡潔ですが、ハッキー):
public static function simplify(expr:Expr):Expr{
switch(expr){
case Mult(left, right):
if(left.enumEq(Const(0)) || right.enumEq(Const(0))) return Const(0);
if(left.enumEq(Const(1))) return right.simplify();
if(right.enumEq(Const(1))) return left.simplify();
if(left.enumConstructor() == right.enumConstructor() &&
left.enumConstructor() == Const(null).enumConstructor())
return Const(Std.int(left.enumParameters()[0] *
right.enumParameters()[0]));
return Mult(left.simplify(), right.simplify());
case Add(left, right): return Add(left.simplify(), right.simplify());
case Neg(expr): return Neg(expr.simplify());
default: return expr;
}
}