2016-05-11 5 views
0

私は以下のケースクラスを持っています。式はボックス化された数学演算と数値です。例えば、addは式のサブクラスであり、式のサブクラスでもあるnumという2つのフィールドを再帰的に含みます。ケースクラスのフィールドをスカラーに追加

abstract class Expression 
    case class num (num: Int) extends Expression 
    case class add (left: Expression, right: Expression) extends Expression 

    abstract class Result 
    case class numericResult (v : Int) extends Result 

は方法は、式を取ることが、その後の操作を実行VHS版と結果でボックスで結果を返すことになって評価するだけでなく、私は削除することはできませんので、ケースクラス戻り、他の種類がありますクラス

def evaluate(expr: Expression) : Result = { 
    expr match { 
     case num(n) => new numericResult(n) 
     case add(l, r) => new numericResult(evaluate(l).v + evaluate(r).v) //add will never be called on imaginary numbers 
     case addi(l, r) => new imaginaryResult(...) //adds imaginary numbers 

    } 
} 

しかし、私はそれを評価しようとすると、私はエラーを取得する:

error: value v is not a member of Result 

Scalaは、lとrがnum型であることを知っていることを確認するにはどうすればよいですか?評価すると、ResultではなくnumericResultが返されますか?私は、評価(l)と評価(r)がnumericResutを返す場合、lとrは私が入れ子になるかもしれないと思います。ここで

+0

を? – Tair

+0

def evaluate(expr:Expression):numericResult = ... – Tair

+0

評価が返すことができるタイプは他にもあります –

答えて

0

は、実行時に、あなたの評価結果を検証した変種です:

def evaluate(expr: Expression) : Result = { 
    expr match { 
     case num(n) => new numericResult(n) 
     case add(l, r) => (evaluate(l), evaluate(r)) match { 
      case (numericResult(l), numericResult(r)) => new numericResult(l + r) 
      case (x, y) => throw new IllegalStateException(s"Numeric Results expected, got $x, $y") 
     } 
     case addi(l, r) => new imaginaryResult(...) //adds imaginary numbers 
    } 
} 

しかし、コンパイル時に型の安全性を得るために、あなたは、たとえば、dependent typesExpressionタイプをほめる考慮すると予想結果の型を必要とします評価の

1

、彼らが生み出すResultの種類によってExpression Sパラメータ化:なぜ、あなたはその後、evaluate` `から` numericResult`を返さない

abstract class Expression[T <: Result] 
case class num (num: Int) extends Expression[numericResult] 
case class add (left: Expression[numericResult], right: Expression[numericResult]) extends Expression[numericResult] 
case class addi (left: Expression[Result], right: Expression[Result]) extends Expression[imaginaryResult] 

abstract class Result 
// why lower-case? 
case class numericResult (v : Int) extends Result 
case class imaginaryResult(v: Int) extends Result 

def evaluate [T <: Result](expr: Expression[T]) : T = { 
    expr match { 
    case num(n) => new numericResult(n) 
    case add(l, r) => new numericResult(evaluate(l).v + evaluate(r).v) //add will never be called on imaginary numbers 
    case addi(l, r) => new imaginaryResult(???) //adds imaginary numbers 
    } 
} 
関連する問題