2015-11-03 81 views
1

這是我的第一個問題,所以我希望我能夠正確地做所有事情。將類型成員類型擴展爲集合

我的情況是這樣的:我想使用類型類來表示特定類型在函數下關閉。具體而言,類型類別被稱爲Substitutable。目的是如果TSubstitutable的一個實例,那麼您可以對其應用替代並獲得T作爲回報。這是通過的每個實例必須實現的方法applySubstitution來實現的。

集合繼承此閉包屬性;如果我將元素替換應用於列表T s,其中TSubstitutable的一個實例,則結果將再次爲T s的列表,因此List[T]本身就是Substitutable的一個實例。

總之,如果T是一個實例,我想使List[T]Substitutable的實例。我看不出如何表達這一點。我看到它的方式,我需要寫類似

implicit objectSubstitutableList[T: Substitutable] extends Substitutable[List[T]], 

但這是不可能的,因爲我不能給一個類型參數的隱式對象。

我該如何解決這個問題?

回答

1

因爲List [T]的類型類型需要隱式參數(T的類型類實例),所以需要一個隱式def。

trait Substitutable[T] { 
    def applySubstitution(value: T, f: String => String): T 
} 

object Substitutable { 
    implicit def listIsSubstitutable[T: Substitutable]: Substitutable[List[T]] = 
    new Substitutable[List[T]] { 
     def applySubstitution(value: List[T], f: String => String): List[T] = 
     value.map(x => implicitly[Substitutable[T]].applySubstitution(x, f)) 
    } 
} 

定義類型類實例的字符串

implicit val stringIsSubstitutable: Substitutable[String] = 
    new Substitutable[String] { 
    def applySubstitution(value: String, f: String => String) = f(value) 
    } 
的列表[字符串]

類型類的實例自動生成

scala> implicitly[Substitutable[List[String]]] 
res3: Substitutable[List[String]] = [email protected] 

這是不行的,因爲沒有可替代性[INT]在隱含的範圍內。

scala> implicitly[Substitutable[List[Int]]] 
<console>:14: error: could not find implicit value for parameter e: Substitutable[List[Int]]