2012-11-10 19 views
4

我想運行下面的Expr類。我已經採取了從http://andymaleh.blogspot.ie/2008/04/scalas-pattern-matching-visitor-pattern.html無法在抽象類中導入案例類

下面這段代碼是什麼,我想:

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) 
    } 

} 

但線

import Expr.Sum 

導致編譯時錯誤: '未找到:對象Expr的'。我如何導入類Expr?

+0

做這些定義來自不同的文件?他們在同一個包裹裏嗎?詳情請。 –

+0

@Aaron Novstrup ive更新了我的問題以顯示代碼的原始來源。 – user701254

+0

@ user701254該鏈接的代碼與我回答的代碼相同,並減去一些花括號。 – Brian

回答

8

您只能實例的輸入部件。所以,你的代碼將是:

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) 
    } 
} 

一個簡單的例子解釋了爲什麼您不能導入非實例成員:

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

如果你能import A.Print,該值將被綁定到x?現在,如果我們這樣做:

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

這是一個原因。 new A(5).Print != new A(5).Print,不僅在平等,而且在類型:val (a1, a2) = (new A(5), new A(5)); implicitly[a1.Print <:< a2.Print]不會編譯的另一個原因。這就是斯卡拉稱爲路徑依賴類型

1

將案例類從抽象類中移出可以進行編譯。在這種情況下它們也處於相同的範圍內,所以沒有任何可導入的東西。

另請注意,import錯誤在此不適用,因爲MainExpr在相同的包中定義。即默認包。

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) 
} 

運行這給:

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

不起作用,因爲您不允許擁有最高級別的defs。將它們包裹在「物體Expr」或類似物體中。 – sschaef