将类型类成员身份扩展到集合



这是我的第一个问题,所以我希望我做的每件事都是正确的。

我的情况是:我想用一个类型类来表示某些类型在函数下是封闭的。具体地说,类型类被称为Substitutable。这样做的目的是,如果TSubstitutable的一个实例,那么您可以对它应用一个替换,并得到一个T作为返回。这是通过Substitutable的每个实例必须实现的方法applySubstitution来实现的。

集合继承此闭包属性;如果我对Ts的列表应用替换元素,其中TSubstitutable的实例,那么结果将再次是Ts的列表,因此List[T]本身就是Substitutable的实例。

简而言之,如果T是实例,那么我想使List[T]成为Substitutable的实例。我不知道该怎么表达。在我看来,我需要写一些类似的东西

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

但这是不可能的,因为我不能给隐式对象一个类型参数。

我该如何解决这个问题?

您需要一个隐式的def,因为List[T]的typeclass需要一个显式参数(T的typeclass实例)。

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

为字符串定义一个typeclass实例

implicit val stringIsSubstitutable: Substitutable[String] =
  new Substitutable[String] {
    def applySubstitution(value: String, f: String => String) = f(value)
  }

List[String]的Typeclass实例自动生成

scala> implicitly[Substitutable[List[String]]]
res3: Substitutable[List[String]] = Substitutable$$anon$2@30376991

这不起作用,因为在隐式作用域中没有可替换[Int]。

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

最新更新