gpt4 book ai didi

scala - 抽象案例类的模式匹配

转载 作者:行者123 更新时间:2023-12-02 04:04:56 25 4
gpt4 key购买 nike

我正在尝试使用依赖方法类型和编译器的夜间构建(2.10.0.r26005-b20111114020239)来抽象模块中的案例类。我从 Miles Sabin' example 中找到了一些灵​​感.

我真的不明白下面的(自包含)代码有什么问题。输出取决于 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)
}
}

任何的想法?

最佳答案

警告是正确的并且是意料之中的,因为从 foo 内部查看, YZ两者都将被抹去,即。 X .

更令人惊讶的是,对Y 的匹配的存在或与 Z 的比赛挫败对X的比赛, IE。在这种情况下,

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

这似乎是合理的,而在较早的比赛之一恢复后,
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)
}
}

结果是,
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,在所有三个实例中都选择了案例被删除到 XY X 之前的案例匹配表达式中的大小写。但是我们在这里处于不受控制的领域,我对自己的直觉并不是 100% 有信心。

关于scala - 抽象案例类的模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8208539/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com