Scala覆盖特征中的通用方法

时间:2018-02-09 09:03:46

标签: scala

我有这样的特质定义:

trait MyTrait {
  def dbService[M[_]]: DBService[M[_]]
  def appConfig: AppConfig
  def supervisorActor: ActorRef
}

我有这个特征的实现,如下所示:

    object MyTrait {

      def apply(system: ActorSystem, actorMaterializer: Materializer): MyTrait = new MyTrait {

        override val appConfig: AppConfig = AppConfig.load()
// Get the ERROR here saying Value dbService overrides nothing        
override val dbService: DBService[Task] = DBServiceT.asTask(appConfig.dbConfig)(scala.concurrent.ExecutionContext.Implicits.global)

        override val supervisorActor: ActorRef =
          system.actorOf(
            SupervisorActor.props(appConfig)(monix.execution.Scheduler.Implicits.global),
            s"${appConfig.appName}-supervisor"
          )
      }
    }

我的DBService特性如下所示:

trait DBService[M[_]] {
  def allPowerPlants(fetchOnlyActive: Boolean): M[Seq[PowerPlantRow]]
  def powerPlantsPaginated(filter: PowerPlantFilter): M[Seq[PowerPlantRow]]
  def allPowerPlantsPaginated(fetchOnlyActive: Boolean, pageNumber: Int): M[Seq[PowerPlantRow]]
  def powerPlantById(id: Int): M[Option[PowerPlantRow]]
  def newPowerPlant(powerPlantRow: PowerPlantRow): M[Int]
}

然后我有一个看起来像这样的实现:

class DBServiceTask private (dbConfig: DBConfig)(implicit ec: ExecutionContext) extends DBService[Task] { self =>

....
....

}

当我尝试这个时,我的MyTrait对象中出现错误:

Value dbService overrides nothing

任何想法我做错了什么?

2 个答案:

答案 0 :(得分:6)

此签名:

def dbService[M[_]]: DBService[M[_]]

描述了可以为任何类型的构造函数M[_]创建DBService的东西。要进行类型检查,它必须能够创建所有

  • DBService[Task]
  • DBService[Future]
  • DBService[Array]
  • DBService[Option]
  • DBService[Ordering]
  • ......等等

由于您的实现只能为单个 M[_](在您的情况下为Task)生成一个值,因此您无法拥有该签名。

您的选项包括将类型参数移动到特征定义,作为类型参数:

trait MyTrait[M[_]] {
  def dbService: DBService[M] // also note that [_] part should not be here
}

或类型成员:

trait MyTrait {
  type M[_]
  def dbService: DBService[M]
}

然而,后者可能会令人讨厌

编辑:您还可以选择直接指定Task

trait MyTrait {
  def dbService: DBService[Task]
}

答案 1 :(得分:0)

val dbService: DBService[Task]DBService[Task]类型的值,而您需要定义一个类型为"参数":def dbService[M[_]]: DBService[M[_]]

的函数

我想你希望你的特质看起来像这样:

trait MyTrait[M[_]] {
  def dbService: DBService[M[_]]
  def appConfig: AppConfig
  def supervisorActor: ActorRef
}