Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 抽象案例类的模式匹配_Scala_Types_Pattern Matching_Type Erasure_Dependent Method Type - Fatal编程技术网

Scala 抽象案例类的模式匹配

Scala 抽象案例类的模式匹配,scala,types,pattern-matching,type-erasure,dependent-method-type,Scala,Types,Pattern Matching,Type Erasure,Dependent Method Type,我试图使用依赖方法类型和编译器的夜间构建(2.10.0.r26005-B201111114020239)来抽象模块中的案例类。我从中得到了一些灵感 我真的不明白下面(自包含的)代码中的错误。输出取决于foo中模式的顺序 // afaik, the compiler doesn't not expose the unapply method // for a companion object trait Isomorphic[A, B] { def apply(x: A): B def u

我试图使用依赖方法类型和编译器的夜间构建(2.10.0.r26005-B201111114020239)来抽象模块中的案例类。我从中得到了一些灵感

我真的不明白下面(自包含的)代码中的错误。输出取决于
foo
中模式的顺序

// afaik, the compiler doesn't not expose the unapply method
// for a companion object
trait Isomorphic[A, B] {
  def apply(x: A): B
  def unapply(x: B): Option[A]
}

// abstract module
trait Module {
  // 3 types with some contraints
  type X
  type Y <: X
  type Z <: X
  // and their "companion" objects
  def X: Isomorphic[Int, X]
  def Y: Isomorphic[X, Y]
  def Z: Isomorphic[Y, Z]
}

// an implementation relying on case classes
object ConcreteModule extends Module {
  sealed trait X { val i: Int = 42 }
  object X extends Isomorphic[Int, X] {
    def apply(_s: Int): X = new X { }
    def unapply(x: X): Option[Int] = Some(x.i)
  }
  case class Y(x: X) extends X
  // I guess the compiler could do that for me
  object Y extends Isomorphic[X, Y]
  case class Z(y: Y) extends X
  object Z extends Isomorphic[Y, Z]
}

object Main {
  def foo(t: Module)(x: t.X): Unit = {
    import t._
    // the output depends on the order of the first 3 lines
    // I'm not sure what's happening here...
    x match {
      // unchecked since it is eliminated by erasure
      case Y(_y) => println("y "+_y)
      // unchecked since it is eliminated by erasure
      case Z(_z) => println("z "+_z)
      // this one is fine
      case X(_x) => println("x "+_x)
      case xyz => println("xyz "+xyz)
    }
  }
  def bar(t: Module): Unit = {
    import t._
    val x: X = X(42)
    val y: Y = Y(x)
    val z: Z = Z(y)
    foo(t)(x)
    foo(t)(y)
    foo(t)(z)
  }
  def main(args: Array[String]) = {
    // call bar with the concrete module
    bar(ConcreteModule)
  }
}
//afaik,编译器不会公开unapply方法
//作为伴星
特征同构[A,B]{
def应用(x:A):B
取消应用def(x:B):选项[A]
}
//抽象模块
特质模块{
//3种类型和一些限制
X型
键入Y println(“z”+z)
//这个很好
案例X(X)=>println(“X”+X)
案例xyz=>println(“xyz”+xyz)
}
}
def条(t:模块):单位={
进口t_
val x:x=x(42)
值y:y=y(x)
val z:z=z(y)
傅(t)(x)
傅(t)(y)
傅(t)(z)
}
def main(参数:数组[字符串])={
//带有具体模块的调用栏
钢筋(混凝土模块)
}
}

有什么想法吗?

警告是正确的,是意料之中的,因为从
foo
中查看,
Y
Z
都将被清除到其界限,即
X

更令人惊讶的是,与
Y
的匹配或与
Z
的匹配阻碍了与
X
的匹配,即在这种情况下

def foo(t: Module)(x: t.X): Unit = {
  import t._
  // the output depends on the order of the first 3 lines
  // I'm not sure what's happening here...
  x match {
    // unchecked since it is eliminated by erasure
    // case Y(_y) => println("y "+_y)
    // unchecked since it is eliminated by erasure
    // case Z(_z) => println("z "+_z)
    // this one is fine
    case X(_x) => println("x "+_x)
    case xyz => println("xyz "+xyz)
  }
}
结果是,

x 42
x 42
x 42
xyz AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97
y AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97
xyz Z(Y(AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97))
这似乎是合理的,但随着早期比赛的恢复

def foo(t: Module)(x: t.X): Unit = {
  import t._
  // the output depends on the order of the first 3 lines
  // I'm not sure what's happening here...
  x match {
    // unchecked since it is eliminated by erasure
    case Y(_y) => println("y "+_y)
    // unchecked since it is eliminated by erasure
    // case Z(_z) => println("z "+_z)
    // this one is fine
    case X(_x) => println("x "+_x)
    case xyz => println("xyz "+xyz)
  }
}
结果是,

x 42
x 42
x 42
xyz AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97
y AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97
xyz Z(Y(AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97))
但事实并非如此:我看不出任何好的理由说明为什么额外的案例会导致选择
xyz
而不是
X
,因此我认为您在模式匹配器中遇到了一个错误。我建议您在Scala JIRA中搜索类似的问题,如果找不到,请打开一个清单,其中包含从上面提取的最小化复制示例


老实说,在上面的第二个示例中,我希望在所有三个实例中都选择了
Y
案例,因为
Y
被擦除为
X
,匹配表达式中
Y
案例在
X
案例之前。但我们现在处于未经检查的领域,我对自己的直觉没有100%的信心。

我刚刚尝试了最新的主干,但它没有为我编译:35:错误:非法依赖方法类型。使用2.10.0.r26037-B201111121020211。有可能它本来就不起作用?只是用2.10.0.r26037-B201111121020211进行了测试,它为我编译。我复制粘贴了整个块,然后
Main.Main(Array())