Scala Dependent类型无法编译

pat*_*rit 4 scala path-dependent-type dependent-type

此代码在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
}
Run Code Online (Sandbox Code Playgroud)

Pipe1编译良好,但Pipe2无法编译为:

value % is not a member of Pipe2.this.Input
     input%2 == 0
          ^
Run Code Online (Sandbox Code Playgroud)

我知道我可以用泛型而不是依赖类型来解决这个问题,但这应该和Pipe2.Inputtypecheck Int来自Pipe1.Output

And*_*kin 6

prev = Pipe构造函数的调用的是不是一个正确的路径,编译器不能将任何类型的信息绑定到这一点,所以你有没有用处结束prev.Output =:= Input了一段不确定prev: Pipe它已经被设置为某事在构造函数中。

只需很小的更改,它就能按预期工作:

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
}
Run Code Online (Sandbox Code Playgroud)

That's why it's called path dependent (not member dependent, not value dependent etc.).