Scala 依赖类型不编译
Scala Dependent type does not compile
此代码应该在 Scala 中编译:
trait Pipe {
type Input
type Output
def apply(input: Input): Output
}
object Pipe {
trait Start extends Pipe {
override type Input = Seq[String]
}
abstract class Connect(val prev: Pipe) extends Pipe {
override type Input = prev.Output
}
}
object Pipe1 extends Pipe.Start {
override type Output = Int
override def apply(input: Input): Output =
input.length
}
object Pipe2 extends Pipe.Connect(prev = Pipe1) {
override type Output = Boolean
override def apply(input: Input): Output =
input%2 == 0
}
Pipe1
编译正常但 Pipe2
编译失败:
value % is not a member of Pipe2.this.Input
input%2 == 0
^
我知道我可以用泛型而不是依赖类型来解决这个问题,但这应该可以工作,因为 Pipe2.Input
应该从 Pipe1.Output
类型检查为 Int
构造函数调用中的 prev = Pipe
不是正确的路径,编译器不能将任何类型信息绑定到它,所以你最终得到一个相当无用的 prev.Output =:= Input
对于一些不确定的prev: Pipe
已在构造函数中设置为 something。
只要稍作改动,它就会按预期工作:
trait Pipe {
type Input
type Output
def apply(input: Input): Output
}
object Pipe {
trait Start extends Pipe {
override type Input = Seq[String]
}
abstract class Connect extends Pipe {
val prev: Pipe
override type Input = prev.Output
}
}
object Pipe1 extends Pipe.Start {
override type Output = Int
override def apply(input: Input): Output =
input.length
}
object Pipe2 extends Pipe.Connect {
val prev = Pipe1
override type Output = Boolean
override def apply(input: Input): Output = input % 2 == 0
}
这就是为什么它被称为 path 依赖(不是 member 依赖,不是 value 依赖等.).
@Andrey-Tyukin 的回答在上面有效。我还发现了这个解决方法:
trait Pipe {
type Input
type Output
def apply(input: Input): Output
}
object Pipe {
trait Start extends Pipe {
override type Input = Seq[String]
}
abstract class Connect[O](val prev: Pipe.Emitting[O]) extends Pipe {
override type Input = O
}
type Emitting[O] = Pipe {type Output = O}
}
object Pipe1 extends Pipe.Start {
override type Output = Int
override def apply(input: Input): Output =
input.length
}
object Pipe2 extends Pipe.Connect(prev = Pipe1) {
override type Output = Boolean
override def apply(input: Input): Output =
input%2 == 0
}
此代码应该在 Scala 中编译:
trait Pipe {
type Input
type Output
def apply(input: Input): Output
}
object Pipe {
trait Start extends Pipe {
override type Input = Seq[String]
}
abstract class Connect(val prev: Pipe) extends Pipe {
override type Input = prev.Output
}
}
object Pipe1 extends Pipe.Start {
override type Output = Int
override def apply(input: Input): Output =
input.length
}
object Pipe2 extends Pipe.Connect(prev = Pipe1) {
override type Output = Boolean
override def apply(input: Input): Output =
input%2 == 0
}
Pipe1
编译正常但 Pipe2
编译失败:
value % is not a member of Pipe2.this.Input
input%2 == 0
^
我知道我可以用泛型而不是依赖类型来解决这个问题,但这应该可以工作,因为 Pipe2.Input
应该从 Pipe1.Output
Int
构造函数调用中的 prev = Pipe
不是正确的路径,编译器不能将任何类型信息绑定到它,所以你最终得到一个相当无用的 prev.Output =:= Input
对于一些不确定的prev: Pipe
已在构造函数中设置为 something。
只要稍作改动,它就会按预期工作:
trait Pipe {
type Input
type Output
def apply(input: Input): Output
}
object Pipe {
trait Start extends Pipe {
override type Input = Seq[String]
}
abstract class Connect extends Pipe {
val prev: Pipe
override type Input = prev.Output
}
}
object Pipe1 extends Pipe.Start {
override type Output = Int
override def apply(input: Input): Output =
input.length
}
object Pipe2 extends Pipe.Connect {
val prev = Pipe1
override type Output = Boolean
override def apply(input: Input): Output = input % 2 == 0
}
这就是为什么它被称为 path 依赖(不是 member 依赖,不是 value 依赖等.).
@Andrey-Tyukin 的回答在上面有效。我还发现了这个解决方法:
trait Pipe {
type Input
type Output
def apply(input: Input): Output
}
object Pipe {
trait Start extends Pipe {
override type Input = Seq[String]
}
abstract class Connect[O](val prev: Pipe.Emitting[O]) extends Pipe {
override type Input = O
}
type Emitting[O] = Pipe {type Output = O}
}
object Pipe1 extends Pipe.Start {
override type Output = Int
override def apply(input: Input): Output =
input.length
}
object Pipe2 extends Pipe.Connect(prev = Pipe1) {
override type Output = Boolean
override def apply(input: Input): Output =
input%2 == 0
}