scala - 具有折叠的抽象类型的模式匹配

标签 scala pattern-matching scala-macros

这是 previous question I asked 的后续行动这远未完成。后面的所有代码都可以在 Scala 控制台中正常编译和运行。

考虑以下抽象数据类型,以及它作为类型类必须支持的操作:

trait SIG {
  type XOrY
  type X <: XOrY
  type Y <: XOrY
}

trait SIGOps[Sig <: SIG] {
  def makeX(s: String): Sig#X
  def makeY(i: Int): Sig#Y
  // the disjunction is enforced with that fold
  def fold[T](xy: Sig#XOrY)(isX: String => T, isY: Int => T): T
  // the following is for convenience, as we want to mimick case classes
  object X {
    def apply(s: String): Sig#X = makeX(s)
    def unapply(xy: Sig#XOrY): Option[String] = fold(xy)(s => Some(s), i => None)
  }
  object Y {
    def apply(i: Int): Sig#Y = makeY(i)
    def unapply(xy: Sig#XOrY): Option[Int] = fold(xy)(s => None, i => Some(i))
  }
}

现在,这是签名的一个可能实现。类型类实例位于伴随对象中以便于发现。

trait EitherSig extends SIG {
  type XOrY = scala.util.Either[String, Int]
  type X = scala.util.Left[String, Int]
  type Y = scala.util.Right[String, Int]
}

object EitherSig {

  implicit object EitherSIGOps extends SIGOps[EitherSig] {
    def makeX(s: String): EitherSig#X = scala.util.Left[String, Int](s)
    def makeY(i: Int): EitherSig#Y = scala.util.Right[String, Int](i)
    def fold[T](xy: EitherSig#XOrY)(isX: String => T, isY: Int => T): T = xy match {
      case Left(s) => isX(s)
      case Right(s) => isY(s)
    }
  }

}

最后,这里是如何编写依赖于抽象签名的代码。

class Example[Sig <: SIG](implicit ops: SIGOps[Sig]) {
  import ops._
  def main(args: Array[String]): Unit = {
    val xy: Sig#XOrY = X("foo")
    xy match {
      case X(s) => println("X: "+s)
      // Scala does not see that the pattern matching is not exhaustive if when I comment the following line
      // case Y(i) => println("Y: "+i)
    }
  }
}

object ConcreteExample extends Example[EitherSig]

它按预期工作:

scala> ConcreteExample.main(Array())
X: foo

问题如下:当模式匹配不像上面那样穷尽时,我如何教 Scala 识别?

可能有 a way to communicate this information to the typechecker但我不知道怎么做。

最佳答案

Jason Zaugg 给了 an answer on Twitter :

[...] we don't have an extension point for that. Only sealed hierarchies are considered.

特拉维斯·布朗 proposed 编写一个检查部分函数的 matchExhaustive 宏,但不认为它是当你得到 fold 时值得麻烦

所以目前这个问题还没有真正的解决方案。

关于scala - 具有折叠的抽象类型的模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23934528/

相关文章:

rust - 我怎样才能对 Option<String> 进行模式匹配?

scala - 为什么此代码在 Scala 2.11 中进行类型检查,我该怎么办?

中缀位置的Scala无类型宏

scala - 直到?处理分块输入。如何?

scala - SBT无法解决Sonatype存储库上存在的依赖项

python - 查找两个字符串共享的所有n字长的子字符串的最大长度

arrays - 数组的最后一个元素匹配 scala

scala - 如何使用宏注释将无参数构造函数添加到 Scala 案例类?

java - 你如何从 Java 调用 Scala 对象?

java - 并行日志聚合的最佳方法