scala类型类可以有抽象类型成员吗?

scala类型类可以有抽象类型成员吗?,scala,generics,types,typeclass,abstract-type,Scala,Generics,Types,Typeclass,Abstract Type,我有这类课程: sealed trait DbValueOps[T <: DbValue] { type R def apply(newContent: R): Option[T] def fromString(newContent: String): Option[T] def isValidContent(newContent: R): Boolean } 但是,当尝试将类型类实例与dbStringOps.isValidContentnewContent(其中newc

我有这类课程:

sealed trait DbValueOps[T <: DbValue] {
  type R
  def apply(newContent: R): Option[T]
  def fromString(newContent: String): Option[T]
  def isValidContent(newContent: R): Boolean
}
但是,当尝试将类型类实例与dbStringOps.isValidContentnewContent(其中newcontent是字符串)一起使用时,我发现类型不匹配:

found   : newContent.type (with underlying type String)
required: database.DbOps.dbStringOps.R

我可以通过将R从抽象类型成员转换为类型参数来实现它,但这很难看,因为在我编写类型类的实现时,R已经被确定了。

在该隐式val上添加类型注释

隐式val dbStringOps:DbValueOps[DbString]{type R=String}=。。。 或

使用此签名接收隐式参数

def fimplicit db:DbValueOps[DbString]{type R=String}=。。。 我也可以这样写

类型AUX[A,T]=DbValueOps[A]{type R=T} def fimplicit db:AUX[DbString,String]=。。。
恵砂川 答案完美地解决了您的问题,但除非您真的希望将设计集中在DbValues上,否则我建议您在这种情况下将隐式设计集中在包装的值字符串上,因为您不需要提供R与字符串的统一

  trait DbValue[T]
  case class DbString(s:String) extends DbValue[String]


  sealed trait DbOps[R]{
    type T <: DbValue[R]
    def apply(newContent: R): Option[T]
    def fromString(newContent: String): Option[T]
    def isValidContent(newContent: R): Boolean
  }

  object DbOps {
    val dbStringOps: DbOps[String] = new DbOps[String] {
      type T = DbString
      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
    }

    val newContent = "hello"
    dbStringOps.isValidContent(newContent)
  }

向DbValue添加类型参数可能会更详细一些,但它会阻止您定义像DbValueOps[DbString]{type R=Int}这样的东西,这可能不是您想要的。

我已经接受了恵砂川 's的回答,因为他们直接回答了我的问题,但我会同意你的设计!什么时候需要这些类型注释?在类型类中使用抽象类型成员时总是这样吗?什么是:调用的类型AUX[A,T]=DbValueOps[A]{type R=T}?我不太明白这是怎么回事。我现在如何使类的方法泛型于dbValueOps?我试图用一个类定义来实现这一点,比如:case class Column[R,T我最终放弃了dbValueOps中的抽象类型成员,但dbValueOps中仍然有一个成员,因为我想在其他类中以通用的方式使用它们,我不知道如何在不使用类型参数的情况下将dbValueOps中函数的返回类型信息获取到这些其他类中。我是这样做的:case class柱[R,T
  trait DbValue[T]
  case class DbString(s:String) extends DbValue[String]


  sealed trait DbOps[R]{
    type T <: DbValue[R]
    def apply(newContent: R): Option[T]
    def fromString(newContent: String): Option[T]
    def isValidContent(newContent: R): Boolean
  }

  object DbOps {
    val dbStringOps: DbOps[String] = new DbOps[String] {
      type T = DbString
      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
    }

    val newContent = "hello"
    dbStringOps.isValidContent(newContent)
  }