2014-09-28 34 views
1

我有以下的情況下類:如何用case類處理簡單的多態性?

object Fields { 
    abstract class Base{ 
    def getString: String 
    } 
    case class A() extends Base{ 
    def getString = "A+++" 
    } 
    case class B() extends Base{ 
    def getString = "B++" 
    } 

    def fieldsToString(fields: List[Base]): String = { 
    fields.tail.foldLeft(s"${fields.head.getString}") {(acc, f) => 
     acc + s",${f.getString}" 
    } 
    } 
} 

然後我試圖調用此函數以下列方式:

val fields = List(A, B, A) 
val result = Fields.fieldsToString(fields) 

使我有以下錯誤:

type mismatch; 
[error] found : List[scala.runtime.AbstractFunction0[Product with Serializable 
with Fields.Base] with Serializable] 

所以我想我需要引入協變:

def fieldsToString[T >: Base](fields: List[T]): String = { 
     fields.tail.foldLeft(s"${fields.head.getString}") {(acc, f) => 
      acc + s",${f.getString}" 
     } 
     } 

,然後給了我下面的編譯錯誤:

do not conform to method fieldsToString's type parameter bounds [T <: Fields.Base] 

到底是什麼問題,這是因外殼班,難道他們不同的表現則正常上課?

回答

0

如果仔細觀察第一條錯誤消息,您會看到您已經創建了一個函數列表。打電話給他們:

val fields = List(A(), B(), A()) 

這是由於隱含具有apply方法同伴對象case類。

1

Rightfold回答很接近,你有沒有真正的功能,但單類型:

Here, p.type is a singleton type, which represents just the object denoted by p. Singleton types by themselves are also useful for supporting chaining of method calls.

scala> case class A() 
defined class A 

scala> A 
res0: A.type = A 

scala> res0() 
res1: A = A() 

談論抽象成員時Odersky的報價the scala overview paper (on page 9, right column)