代码之家  ›  专栏  ›  技术社区  ›  bbarker

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

  •  0
  • bbarker  · 技术社区  · 8 年前

      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 其typeclass实例定义为:

      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 回复  |  直到 8 年前
        1
  •  1
  •   Dmytro Mitin    8 年前

    您应该正确声明隐式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
    }
    
    推荐文章