2015-11-03 71 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]]