我正在尝试计算一些以后需要引用的类型。
我试图通过将类型存储在类型成员中来实现这一目标。
这是一个例子:
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
在我看来,我正在表达一些可以接受的内容,但是由于某种原因,编译器无法理解我要执行的操作(或者我错了)。
为什么会出现类型错误?有解决方法吗?
答案 0 :(得分:2)
关于类型系统,可能会有一些错误,尤其是在val (instance1, instance2) =
行中,因为在 if 中,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)
}
}
一些注释,总是比隐式 {更倾向于隐式 vals
和defs
具有特定类型签名的{ {1}},因为对象的类型为objects
,所以它们倾向于弄乱类型系统。
另外,将您的实现隐藏在工厂构造函数的后面,以将其类型映射到父级ThatObjectName.type
。