2

次の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;
    }
}
4

1 に答える 1

3

Haxeは現在、深いパターンマッチングをサポートしていません。これは、バージョン3.0で実装されているものの1つです。

于 2012-11-13T06:20:27.577 に答える