Unable to import case class in abstract class

I want to run the Expr class below. I took this code from http://andymaleh.blogspot.ie/2008/04/scalas-pattern-matching-visitor-pattern.html

Here is what I am trying:

import Expr.Sum object Main { def main(args:Array[String]) { var expr1 = new Sum(new Num(1), new Prod(new Num(2), new Num(3))) print(expr1) } } abstract class Expr { case class Num(n: Int) extends Expr case class Sum(l: Expr , r: Expr) extends Expr case class Prod(l: Expr, r: Expr) extends Expr def evalExpr(e: Expr): Int = e match { case Num(n) => n case Sum(l, r) => evalExpr(l) + evalExpr(r) case Prod(l, r) => evalExpr(l) * evalExpr(r) } def printExpr(e: Expr) : Unit = e match { case Num(n) => print(" " + n + " ") case Sum(l, r) => printExpr(l); print("+"); printExpr(r) case Prod(l, r) => printExpr(l); print("x"); printExpr(r) } } 

But the line

 import Expr.Sum 

raises a compile-time error: 'not found: object Expr'. How to import an Expr class?

+4
source share
2 answers

You can only import instances of instances. So your code will look like this:

 object Main { def main(args:Array[String]) { val expr = new Expr {} // now we have a instance. import expr._ var expr1 = new Sum(new Num(1), new Prod(new Num(2), new Num(3))) print(expr1) } } 

A simple example explains why you cannot import members other than instances:

 class A(val x:Int) { object Print { def print = println(x) } } 

If you could import A.Print , what value would be bound to x ? Now if we do this:

 val a = new A(5); // we have a value bound to x. import a._ Print.print 

This is one of the reasons. Another reason why new A(5).Print != new A(5).Print not only in equality, but also in type: val (a1, a2) = (new A(5), new A(5)); implicitly[a1.Print <:< a2.Print] val (a1, a2) = (new A(5), new A(5)); implicitly[a1.Print <:< a2.Print] will not compile. This is what Scala calls path dependent types.

+8
source

Moving case classes from an abstract class requires compilation. In this case, they are also in the same volume, so there is nothing to import.

Also note that the import error does not apply here, since Main and Expr defined in the same package. that is, the default package.

 object Main { def main(args:Array[String]) { var expr1 = new Sum(new Num(1), new Prod(new Num(2), new Num(3))) print(expr1) } } abstract class Expr { } case class Num(n: Int) extends Expr case class Sum(l: Expr , r: Expr) extends Expr case class Prod(l: Expr, r: Expr) extends Expr def evalExpr(e: Expr): Int = e match { case Num(n) => n case Sum(l, r) => evalExpr(l) + evalExpr(r) case Prod(l, r) => evalExpr(l) * evalExpr(r) } def printExpr(e: Expr) : Unit = e match { case Num(n) => print(" " + n + " ") case Sum(l, r) => printExpr(l); print("+"); printExpr(r) case Prod(l, r) => printExpr(l); print("x"); printExpr(r) } 

Running this gives:

 scala>Main.main(Array[String]()) Sum(Num(1),Prod(Num(2),Num(3))) 
+1
source

Source: https://habr.com/ru/post/1445173/


All Articles