3

I'm new to scala and I'm not sure how to call the abstract class to create the desired object. any help would be great

abstract class Expr{
    case class Number(n:Double) extends Expr
    case class Sum(e1:Expr, e2: Expr) extends Expr
    case class Subtract(e1: Expr, e2: Expr) extends Expr
    case class Divide(e1: Expr, e2: Expr) extends Expr
    case class Abs(e1: Expr) extends Expr
    case class Mod(e1: Expr, e2: Expr) extends Expr
    def eval(e:Expr): Double = e match{
        case Number(n) => n;
        case Sum(e1,e2) => eval(e1) + eval(e2);
    }
}
object main{
    def main(args: Array[String])  {
        val e = Expr();
        println("hello");
    }
}

so i want to be able to create Expr object and use eval on it. Thanks.

Knitex
  • 225
  • 1
  • 6
  • 11

4 Answers4

8

You can instantiate Expr by adding {} to indicate an empty classbody. So your code would work if you wrote

val e = Expr() {};
val n = e.Number(1.0);
val sum = e.Sum(n, n);
println(e.eval(sum));

But I don't see why the case classes has to reside inside the Expr class. Why not write something like:

abstract class Expr {}

object Eval {
  def apply(e : Expr) = e match{
    case Number(n) => n;
    case Sum(e1,e2) => Eval(e1) + Eval(e2);
  }
}

case class Sum(e1 : Expr, e2 : Expr) extends Expr

Then you can reference them much nicer:

Eval(Sum(Number(1), Number(1)))
Jens Egholm
  • 2,730
  • 3
  • 22
  • 35
4

What about that:

abstract class Expr {
  def eval: Double
}
case class Number(n:Double) extends Expr {
  def eval = n
}
case class Sum(e1:Expr, e2: Expr) extends Expr {
  def eval = e1.eval + e2.eval
}
case class Subtract(e1: Expr, e2: Expr) extends Expr {
  def eval = e1.eval - e2.eval
}

object Eval {
  def apply(e : Expr) = e.eval
}
SHildebrandt
  • 306
  • 1
  • 8
1

[update]

BTW I prefer @JensEgholm Eval object (with apply method) to my recommendation of adding eval to main below. My point is that your eval code should be part of a Scala object for easy access and not part of any Scala abstract class.

[original]

That looks like sample/template code from Odersky's Programming in Scala (which I highly recommend by the way)

If so, you copied the template incorrectly. There is no brace after abstract class Expr That one line is a complete abstract class declaration. Also the eval method should go in your main object. Try this:

abstract class Expr
case class Number(n:Double) extends Expr
case class Sum(e1:Expr, e2: Expr) extends Expr
case class Subtract(e1: Expr, e2: Expr) extends Expr
case class Divide(e1: Expr, e2: Expr) extends Expr
case class Abs(e1: Expr) extends Expr
case class Mod(e1: Expr, e2: Expr) extends Expr

object main{
  def eval(e:Expr): Double = e match{
      case Number(n) => n;
      case Sum(e1,e2) => eval(e1) + eval(e2);
  }
    def main(args: Array[String])  {
      val n = Number(1.0);
      val m = Number(2.0);
        println(eval(Sum(n,m)));
    }
}

The program should print "3.0".

Guido Simone
  • 7,912
  • 2
  • 19
  • 21
1

As per Odersky, if you're new to scala you should be using traits in most cases unless you know why to use an abstract class in partucular.

What is the advantage of using abstract classes instead of traits?

Examples above will be legal with traits and can then be 'mixed in' together.

scala> trait Expr
defined trait Expr

scala> case class Number(n:Double) extends Expr
defined class Number
Community
  • 1
  • 1
JasonG
  • 5,794
  • 4
  • 39
  • 67