识别模式匹配器中的错误

时间:2012-08-27 23:59:43

标签: scala pattern-matching

我刚才有另一种模式匹配错误。

谷歌找到了很多。此google请求应首先在任何akka文档中链接,以便向用户提供有关scala中基于消息的编程的艰辛信息的公平信息。

有些错误已经解决,有些则没有。它们是通用的,不同的代码片段可能会应用于一个bug。

我有一件仍然停止在2.9.2中工作,我想知道错误状态。所以我需要熟悉scala bug数据库的人的帮助,他们可以向我指出与我的代码相对应的错误。

示例代码:

object Test {
  sealed trait Pattern[T] {
    val data : T
  }
  object Pattern {
    def apply[T](data : T) : Pattern[T] = Primary(data)
    def apply[T](data : T, f : Float) : Pattern[T] = Full(data,f)
    def unapply[T](pat : Pattern[T]) : Option[T] = Some(pat.data)
  }
  final case class Primary[T](data : T) extends Pattern[T]
  final case class Full[T](data : T, f: Float) extends Pattern[T]

  val recognize1 : PartialFunction[Pattern[Any],Unit] = {
    case pat@Pattern(d) => println("pattern recognized: " + pat)
    case _ => println("simple failed")
  }
  val recognize2 : PartialFunction[Pattern[Any],Unit] = {
    case pat@Full(x : Int, f) => println("full@Int detected: " + pat)
    case pat@Pattern(c : Float) => println("pat@Float detected: " + pat)
    case _ => println("full-pattern detection failed")
  }
  val recognize3 : PartialFunction[Pattern[Any],Unit] = {
    case pat@Pattern(x : Int) => println("pat@Int detected: " + pat)
    case pat@Pattern(c : Float) => println("pat@Float detected: " + pat)
    case _ => println("pattern-pattern detection failed")
  }
  val recognize4 : PartialFunction[Pattern[Any],Unit] = {
    case pat@Full(x : Int, f) => println("full@Int detected: " + pat)
    case pat@Full(c : Float, f) => println("full@Float detected: " + pat)
    case _ => println("full-full detection failed")
  }
  val allRecognize : List[PartialFunction[Pattern[Any],Unit]] =
    List( recognize1, recognize2, recognize3, recognize4)

  val tests : List[Any] = List(3) ++ List(5.0f)

  def testAll() = for (t <- tests) {
    println("test: " + t)
    val primary = Pattern(t)
    for (r <- allRecognize) r(primary)
    val full = Pattern(t,1.0f)
    for (r <- allRecognize) r(full)
    println("")
  }
}

和相应的输出:

scala> Test.testAll()
test: 3
pattern recognized: Primary(3)
full-pattern detection failed
pat@Int detected: Primary(3)
full-full detection failed
pattern recognized: Full(3,1.0)
full@Int detected: Full(3,1.0)
pat@Int detected: Full(3,1.0)
full@Int detected: Full(3,1.0)

test: 5.0
pattern recognized: Primary(5.0)
pat@Float detected: Primary(5.0)
pat@Float detected: Primary(5.0)
full-full detection failed
pattern recognized: Full(5.0,1.0)
full-pattern detection failed
pat@Float detected: Full(5.0,1.0)
full@Float detected: Full(5.0,1.0)

测试Int效果很好,因为Int首先匹配。

匹配Float会出现问题。当我为Int和Float(Pattern或Full)使用相同的提取器时,一切正常。但是当我混合提取器并尝试使用Full提取Int并尝试Float with Pattern时,一切都会出错。

主要问题:它是什么错误(你真的应该知道scala内部想出来的吗?)

小问题:对此最优雅的解决方法是什么?

模式特征被写成(U,Option [V])的漂亮(并且内存效率更高的替代)

2 个答案:

答案 0 :(得分:2)

在Scala-2.10.0-M6上,您的代码将打印以下内容:

scala> testAll()
test: 3
pattern recognized: Primary(3)
full-pattern detection failed
pat@Int detected: Primary(3)
full-full detection failed
pattern recognized: Full(3,1.0)
full@Int detected: Full(3,1.0)
pat@Int detected: Full(3,1.0)
full@Int detected: Full(3,1.0)

test: 5.0
pattern recognized: Primary(5.0)
pat@Float detected: Primary(5.0)
pat@Float detected: Primary(5.0)
full-full detection failed
pattern recognized: Full(5.0,1.0)
pat@Float detected: Full(5.0,1.0)
pat@Float detected: Full(5.0,1.0)
full@Float detected: Full(5.0,1.0)

Full(5.0f, 1.0f)现在匹配Pattern(c: Float),其他测试似乎可以正常工作。

答案 1 :(得分:1)

现在搜索模式匹配器上的错误是非常无用的,除非您在2.10.x或master上测试代码。有两个原因:

  • 模式匹配器中存在很多错误,找到合适的错误非常困难。
  • 2.10.x上的代码是全新的,因此旧模式匹配器上的错误与新模式匹配器无关(它修复了大部分,如果不是全部的话)。