Can a scala type class have abstract type members?

Fre*_*ens 0 generics types scala typeclass abstract-type

I have this type class:

sealed trait DbValueOps[T <: DbValue] {
  type R
  def apply(newContent: R): Option[T]
  def fromString(newContent: String): Option[T]
  def isValidContent(newContent: R): Boolean
}
Run Code Online (Sandbox Code Playgroud)

with this type class instance:

package object DbOps {
  implicit val dbStringOps: DbValueOps[DbString] = new DbValueOps[DbString] {
    type R = String
    def apply(newContent: String): Option[DbString] =
      isValidContent(newContent) match {
        case true => Some(new DbString(newContent))
        case false => None
      }
    def fromString(newContent: String): Option[DbString] = this(newContent)
    def isValidContent(newContent: String): Boolean = !newContent.isEmpty
  }
}
Run Code Online (Sandbox Code Playgroud)

But when trying to use the type class instance with something like dbStringOps.isValidContent(newContent) where newcontent is a string, i get a type mismatch:

found   : newContent.type (with underlying type String)
required: database.DbOps.dbStringOps.R
Run Code Online (Sandbox Code Playgroud)

I can get it to work by converting R from an abstract type member to a type parameter, but that is ugly since R is already determined when i'm writing the implementation of the type class.

恵砂川*_*恵砂川 7

在其上添加类型注释implicit val

implicit val dbStringOps: DbValueOps[DbString] { type R = String } = ...
Run Code Online (Sandbox Code Playgroud)

要么

使用此签名接收隐式参数。

def f()(implicit db: DbValueOps[DbString] { type R = String }) = ...
Run Code Online (Sandbox Code Playgroud)

也可以这样写

type AUX[A, T] = DbValueOps[A] { type R = T }

def f()(implicit db: AUX[DbString, String]) = ...
Run Code Online (Sandbox Code Playgroud)