views:

94

answers:

1

I want create a special calculator. I think that case class is a good idea for operations:

sealed class Expr
case class add(op1:Int, op2:Int) extends Expr
case class sub(op1:Int, op2:Int) extends Expr
case class mul(op1:Int, op2:Int) extends Expr
case class div(op1:Int, op2:Int) extends Expr
case class sqrt(op:Int) extends Expr
case class neg(op:Int) extends Expr
/* ... */

Now I can use match-case for parsing input. Maybe, I should also use traits (ie: trait Distributivity, trait Commutativity and so on), Is that posible? Is that a good idea?

+5  A: 

Before you start adding traits of not-so-clear additional value, you should get the basics right. The way you do it now makes these classes not very useful, at least not when building a classical AST (or "parse tree"). Imagine 4 * (3+5). Before you can use the multiplication operation, you have to evaluate the addition first. That makes things complicated. What you usually want to have is the ability to write your formula "at once", e.g. Mul(4,Add(3, 5)). However that won't work that way, as you can't get Ints or Doubles into your own class hierarchy. The usual solution is a wrapper class for Numbers, say "Num". Then we have: Mul(Num(4),Add(Num(3), Num(5)). This might look complicated, but now you have "all at once" and you can do things like introducing constants and variables, simplification (e.g. Mul(Num(1),x) --> x), derivation...

To get this, you need something along the lines

sealed trait Expr {
  def eval:Int      
}
case class Num(n:Int) extends Expr {
  def eval = n
}
case class Neg(e: Expr) extends Expr {
  def eval = - e.eval() 
}
case class Add(e1: Expr, e2: Expr) extends Expr {
  def eval = e1.eval + e2.eval  
}
...

Now you can write a parser that turns "4*(3+5)" into Mul(Num(4),Add(Num(3), Num(5)), and get the result by calling eval on that expression.

Scala contains already a parse library called parser combintators. For an example close to the code above see http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html

Landei
Yes! But I don't refer that. Maybe I have explained wrong.
isola009
@isola009 Landei donated his time and energy to write this answer. If his answer isn't suitable, please take the time to clarify your question.
Aaron Novstrup
My english is very poor, i don't know carify my question. Sorry.
isola009
Aaron Novstrup
I really want to do is more complex. That is just one example. What I do is a good design. Generic answers would enough.
isola009