如何使用类型成员约束与类型类一起使用?

时间:2018-08-23 20:03:14

标签: scala

我有一个带有签名的函数,如下所示:

  def runInSystem[J](job: J)
  (implicit ev: Job[J] {type M <: SysJobMetaData},
   asys: ActorSystem, jobContextService: JobContextService
  ): IO[Nothing, RunResult] = ...

当我这样调用此函数时:

  case cmd: OneShot =>
    memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)(jobOneShot, asys, jobContextService)))
    cmd

我得到一个错误:

[error] /home/brandon/workspace/CCRS/web-server/src/main/scala/org/xsede/jobrunner/server/InMemService.scala:65: type mismatch;
[error]  found   : org.xsede.jobrunner.model.ModelApi.OneShot.jobOneShot.type (with underlying type org.xsede.jobrunner.model.ModelApi.Job[org.xsede.jobrunner.model.ModelApi.OneShot])
[error]  required: org.xsede.jobrunner.model.ModelApi.Job[org.xsede.jobrunner.model.ModelApi.OneShot]{type M <: org.xsede.jobrunner.model.ModelApi.SysJobMetaData}
[error]         memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)(jobOneShot, asys, jobContextService)))

这个错误对我来说没有多大意义,所以我想知道我是否在Scala的类型系统中遇到了限制。原因是OneShot及其类型类实例定义为:

  final case class OneShot(id: JobId, cmd: String, meta: SysJobMetaData) {
    type M = SysJobMetaData
  }

implicit val jobOneShot: Job[OneShot] = new Job[OneShot] {
  def id(jb: OneShot): JobId = jb.id
  def cmd(jb: OneShot): String = jb.cmd
  override type M = SysJobMetaData
  def meta(jb: OneShot): M = jb.meta
}

因此,根据定义,我认为应该满足约束type M <: SysJobMetaData

1 个答案:

答案 0 :(得分:1)

您应该正确声明隐式val的类型。

尝试

implicit val jobOneShot: Job[OneShot] { type M = SysJobMetaData } = new Job[OneShot] {
  def id(jb: OneShot): JobId = jb.id
  def cmd(jb: OneShot): String = jb.cmd
  override type M = SysJobMetaData
  def meta(jb: OneShot): M = jb.meta
}