scala – 在类型类中,如何通过额外的参数改变操作?


Scala类型类中,将存在定义操作的特征,例如, NumberLike with plus()和minus(),Transformer with transform(),或AddressLabelMaker with toLabel().然后可以使用类型类成员扩展特征.

通常,操作对于不同的成员将具有相同数量的参数,即签名看起来非常相似.我的问题是:如果一个成员需要基本上相同的操作,但是有一个额外的参数(可能只是一个隐含的参数:根据上下文修改操作的东西)会发生什么?

有没有办法在不定义全新(类似)类型类的情况下执行此操作?

最佳答案 有一个额外的显式参数?不可以.每个类型类实例必须具有相同的接口,类型类的接口.有隐含参数?是.您可以声明一个隐式def,它返回所需的隐式,但它本身需要一个隐式.这是一个例子来解释:

case class Cat(name: String)
case class Person(name: String)
case class Silverware(kind: String)

implicit object GoodSilver extends Silverware("the good silver")

trait AnimalFeeder[A] {
  def feed(animal: A): Unit
}

implicit object CatFeeder extends AnimalFeeder[Cat] {
  def feed(cat: Cat) = println(cat.name + " eats cat food!")
}

implicit def personFeeder(implicit silverware: Silverware) =
  new AnimalFeeder[Person] {
    def feed(person: Person) =
      println(person.name + " eats people food with " + silverware.kind)
  }

def feedAnimal[A](a: A)(implicit feeder: AnimalFeeder[A]) = feeder.feed(a)

CatFeeder提供隐含的猫喂猫任何猫. personFeeder是一个def,它可以创建一个隐式来提供Person,但需要一个隐式的Silverware.所以在调用中:

feedAnimal(Person("John"))

编译器将搜索隐式的AnimalFeeder [Person],找到personFeeder,然后搜索隐式Silverware,最后找到GoodSilver.

重要的是要注意personFeeder不是隐式转换.尽管是从Silverware到AnimalFeeder [Person]的方法,它永远不会隐式转换Silverware.这是因为其参数被标记为隐式,隐式转换必须使其参数显式.

点赞