Scala Dependent类型无法编译

时间:2019-04-02 23:33:02

标签: scala dependent-type path-dependent-type

此代码应该在Scala中编译:

try {
    Request _rbuilder = new Request.Builder()
                        .url(url)
                        .addHeader("Content-Type", "application/json; charset=utf-8")
                        .post(_parameters)
                        .build();
    Response _res= _client.newCall(_rbuilder).execute();
    return _res.body().string();
} catch (Exception ex) {
    Log.i("Error task", ex.toString());
}

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的{​​{1}}

2 个答案:

答案 0 :(得分:5)

构造函数调用中的prev = Pipe东西不是正确的路径,编译器无法将任何类型信息绑定到该路径,因此对于一些不确定的{{ 1}},该值已在构造函数中设置为 something

只需很小的更改,即可按预期工作:

prev.Output =:= Input

这就是为什么它被称为 path 依赖(不是 member 依赖,不是 value 依赖等)。

答案 1 :(得分:1)

@ 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
}