Scala 类型安全向量实现的类型不匹配
我正在尝试实现类型级向量。在我尝试实现函数Scala 类型安全向量实现的类型不匹配,scala,type-level-computation,Scala,Type Level Computation,我正在尝试实现类型级向量。在我尝试实现函数add之前,一切都很顺利,这意味着要添加两个向量(维度相同) 这就是我到目前为止所做的: object Vector { type Vector1[A] = Ex[A, Vector0[A]] def of[A](a1: A): Vector1[A] = Ex(Vector0[A](), a1) type Vector2[A] = Ex[A, Vector1[A]] def of[A](a1: A, a2: A): Vector2
add
之前,一切都很顺利,这意味着要添加两个向量(维度相同)
这就是我到目前为止所做的:
object Vector {
type Vector1[A] = Ex[A, Vector0[A]]
def of[A](a1: A): Vector1[A] = Ex(Vector0[A](), a1)
type Vector2[A] = Ex[A, Vector1[A]]
def of[A](a1: A, a2: A): Vector2[A] = of(a1).ex(a2)
type Vector3[A] = Ex[A, Vector2[A]]
def of[A](a1: A, a2: A, a3: A): Vector3[A] = of(a1, a2).ex(a3)
}
trait Vector[A] {
type Same[B] <: Vector[B]
type Self <: Vector[A]
def ex(a: A): Vector[A]
def add(that: Self): Self
def map[B](f: A => B): Same[B]
def forEach(f: A => Unit): Unit
}
case class Vector0[A]() extends Vector[A] {
type Same[B] = Vector0[B]
type Self = Vector0[A]
def ex(that: A): Ex[A, Self] = Ex[A, Self](this, that)
def add(that: Self): Self = Vector0[A]()
def map[B](f: A => B): Same[B] = Vector0[B]()
def forEach(f: A => Unit): Unit = ()
}
case class Ex[A, V <: Vector[A]](v: V, a: A) extends Vector[A] {
type Same[B] = Ex[B, V#Same[B]]
type Self = Ex[A, V]
def ex(that: A): Ex[A, Self] = Ex[A, Self](this, that)
def add(that: Self)(implicit num: Numeric[A]): Self = Ex[A, V](v.add(that.v), num.plus(a, that.a))
def map[B](f: A => B): Same[B] = Ex[B, V#Same[B]](v.map(f), f(a))
def forEach(f: A => Unit): Unit = {
v.forEach(f)
f(a)
}
}
这对我来说没有意义,因为v
和都保证.v
是v
类型
我正在将mill
与Scala2.13.0-M5
一起使用
我遗漏了什么?问题是
向量
中的类型Self
是抽象的,仅为向量
的非抽象子类定义。可以有Vector
类型的值,但编译器无法知道该值的Self
类型。因此,无法对该值调用add
,因为无法检查参数是否为正确的类型(因为类型未知)
在您的
Ex
类中,值v
不是类型v,只是一个观察:案例类Ex
中的add()
方法不会覆盖特征向量[]
中继承的(和抽象的)add()
方法。隐式参数提供了一个不同的配置文件。谢谢,我想我现在理解了这个问题。但是你知道我怎么解决吗?
[error] found : that.v.type (with underlying type V)
[error] required: Ex.this.v.Self
[error] def add(that: Self)(implicit num: Numeric[A]): Self = Ex[A, V](v.add(that.v), num.plus(a, that.a))
^
trait A {
type Self // Abstract type
def add(a: Self, b: Self): Self
}
case class A1() extends A {
type Self = Int // Concrete type
def add(a: Int, b: Int) = a + b
}
case class A2() extends A {
type Self = String // Concrete type
def add(a: String, b: String) = a + b
}
val a1 = new A1
val a2 = new A2
a1.add(1, 1) // Argument type is Int
a2.add("A", "B") // Argument type is String
val a: A = a1
a.add(1, 1) // fails to compile
a.add("A", "B") // fails to compile