构成特征时Scala类型不匹配

构成特征时Scala类型不匹配,scala,generics,types,Scala,Generics,Types,我试图计算一些我以后需要参考的类型 我试图通过将类型存储在类型成员中来实现这一点 下面是一个例子: trait TypeClass[A] { def op(x: A): A } object TypeClass { implicit object FloatIsTypeClass extends TypeClass[Float] { override def op(x: Float) = x } implicit object DoubleI

我试图计算一些我以后需要参考的类型

我试图通过将类型存储在类型成员中来实现这一点

下面是一个例子:

trait TypeClass[A] {
    def op(x: A): A
}

object TypeClass {

    implicit object FloatIsTypeClass extends TypeClass[Float] {
        override def op(x: Float) = x
    }

    implicit object DoubleIsTypeClass extends TypeClass[Double] {
        override def op(x: Double) = x
    }
}


object TraitBounds {

    trait Types1 {
        type Member1
        val cls1: TypeClass[Member1]
    }

    class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
        type Member1 = A
        override val cls1 = ev
    }

    trait Types2 {
        type Member2
        val cls2: TypeClass[Member2]
    }

    class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
        type Member2 = A
        override val cls2 = ev
    }

    trait AllTypes extends Types1 with Types2

    def mk(x: Int): AllTypes = {
        import TypeClass._

        val (instance1, instance2) =
            if (x == 1) {
                (new Types1Impl[Float](), new Types2Impl[Double]())
            } else {
                (new Types1Impl[Double](), new Types2Impl[Float]())
            }

        new AllTypes {
            override type Member1 = instance1.Member1
            override val cls1 = instance1.cls1
            override type Member2 = instance2.Member2
            override val cls2 = instance2.cls2
        }
    }

    def main(args: Array[String]): Unit = {
        val in = mk(1)
        println(in)
    }

}
我得到以下错误:

Error:(54, 43) type mismatch;
 found   : TypeClass[_1]
 required: TypeClass[this.Member1]
    (which expands to)  TypeClass[_1]
            override val cls1 = instance1.cls1
在我看来,我表达的东西应该是可以接受的,但出于某种原因,编译器不理解我试图做什么(或者可能我错了)


为什么会出现类型错误?有解决方法吗?

可能存在一些关于类型系统的错误,尤其是在这行
val(instance1,instance2)=
中,因为在的一个分支中,如果
instance1
的类型为
Types1Impl[Float]
,而在另一个分支中的类型为
Types1Impl[Double]
,它可能被推断为类型
Types1Impl[AnyVal]
,也许这就是问题的原因,但我对编译器了解不多,不知道确切的原因

不过,我对您的代码进行了一点重构,它对我来说很有用

trait TypeClass[A] {
  def op(x: A): A
}

object TypeClass {
  implicit val FloatIsTypeClass: TypeClass[Float] = new TypeClass[Float] {
    override def op(x: Float): Float = x
  }

  implicit val DoubleIsTypeClass: TypeClass[Double] = new TypeClass[Double] {
    override def op(x: Double): Double = x
  }
}

object TraitBounds {
  trait Types1 {
    type Member1
    val cls1: TypeClass[Member1]
  }

  object Types1 {
    private class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
      override type Member1 = A
      override val cls1 = ev
    }

    def apply[A: TypeClass]: Types1 = new Types1Impl[A]
  }

  trait Types2 {
    type Member2
    val cls2: TypeClass[Member2]
  }

  object Types2 {
    private class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
      override type Member2 = A
      override val cls2 = ev
    }

    def apply[A: TypeClass]: Types2 = new Types2Impl[A]
  }

  trait AllTypes extends Types1 with Types2
  object AllTypes {
    def fromTypes(t1: Types1, t2: Types2): AllTypes = new AllTypes {
      override type Member1 = t1.Member1
      override val cls1 = t1.cls1
      override type Member2 = t2.Member2
      override val cls2 = t2.cls2
    }
  }

  def mk(x: Int): AllTypes =
    if (x == 1) {
      AllTypes.fromTypes(Types1[Float], Types2[Double])
    } else {
      AllTypes.fromTypes(Types1[Double], Types2[Float])
    }

  def main(args: Array[String]): Unit = {
    val in: AllTypes = mk(1)
    println(in)
  }
}
注意,与隐式
对象相比,总是更喜欢带有特定类型签名的隐式
VAL
defs
,它们往往会弄乱类型系统,因为对象的类型是
ThatObjectName.type

另外,将您的实现隐藏在工厂构造函数后面,将它们的类型隐藏到父
trait
可能存在一些关于类型系统的错误,特别是在这一行
val(instance1,instance2)=
,由于在的一个分支中,如果
实例1
的类型为
Types1Impl[Float]
,而在另一个分支中的类型为
Types1Impl[Double]
,则可以推断为类型
Types1Impl[AnyVal]
,可能这就是问题的原因,但我对编译器了解不多,不知道确切的原因

不过,我对您的代码进行了一点重构,它对我来说很有用

trait TypeClass[A] {
  def op(x: A): A
}

object TypeClass {
  implicit val FloatIsTypeClass: TypeClass[Float] = new TypeClass[Float] {
    override def op(x: Float): Float = x
  }

  implicit val DoubleIsTypeClass: TypeClass[Double] = new TypeClass[Double] {
    override def op(x: Double): Double = x
  }
}

object TraitBounds {
  trait Types1 {
    type Member1
    val cls1: TypeClass[Member1]
  }

  object Types1 {
    private class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
      override type Member1 = A
      override val cls1 = ev
    }

    def apply[A: TypeClass]: Types1 = new Types1Impl[A]
  }

  trait Types2 {
    type Member2
    val cls2: TypeClass[Member2]
  }

  object Types2 {
    private class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
      override type Member2 = A
      override val cls2 = ev
    }

    def apply[A: TypeClass]: Types2 = new Types2Impl[A]
  }

  trait AllTypes extends Types1 with Types2
  object AllTypes {
    def fromTypes(t1: Types1, t2: Types2): AllTypes = new AllTypes {
      override type Member1 = t1.Member1
      override val cls1 = t1.cls1
      override type Member2 = t2.Member2
      override val cls2 = t2.cls2
    }
  }

  def mk(x: Int): AllTypes =
    if (x == 1) {
      AllTypes.fromTypes(Types1[Float], Types2[Double])
    } else {
      AllTypes.fromTypes(Types1[Double], Types2[Float])
    }

  def main(args: Array[String]): Unit = {
    val in: AllTypes = mk(1)
    println(in)
  }
}
注意,与隐式
对象相比,总是更喜欢带有特定类型签名的隐式
VAL
defs
,它们往往会弄乱类型系统,因为对象的类型是
ThatObjectName.type
另外,将实现隐藏在工厂构造函数后面,将它们的类型隐藏到父
trait