3

=>详尽的模式匹配很棒,但它似乎只适用于 case ( ) 运算符的左侧。

我很好奇是否有人可以验证函数(或表达式)的输出是否可以绑定到该枚举。目标是让编译器在我忘记从枚举中输出项目时告诉我。

在我的示例中,我使用了以下包含三个项目的枚举:

object MyEnum { 
    sealed trait t 
    case object E1 extends t
    case object E2 extends t
    case object E3 extends t
}

这是一个模式匹配表达式,它会产生编译时警告(我们已经知道):

def foo( e : MyEnum.t ) : Boolean =
    e match {
        case MyEnum.E1 => true
        case MyEnum.E2 => false
        case MyEnum.E3 => true   // if we leave this line out, we get a warning
    }

如果我们省略了模式匹配表达式,Scala 会抱怨MyEnum.E3,引用非详尽的模式匹配。这是非常有益的,但我想知道是否可以反过来。

MyEnum.t我们能解释右边的所有情况=>吗?

这是一个突出显示这一点的示例:

def bar( s : String ) : Option[MyEnum.t] = 
    s match {
        case "a" => Some(MyEnum.E1)
        case "b" => Some(MyEnum.E2)
        case "c" => Some(MyEnum.E3)  // if we leave this out, no warning
        case _ => None
    }

在这个例子中,如果我们省略了带有 的行MyEnum.E3,那么编译器就会继续运行,就好像没有任何问题一样。我想做的断言是:

forall MyEnum.t (aliased as e) there exists Some(e) | None

我知道这可以很容易地通过运行时测试来解决,但我很好奇是否有一种方法可以静态地检查它。

谢谢。

4

2 回答 2

0

我要靠运气并声称这是不可能的(让我们对奥德斯基保密)。如果 Scala 编译器能够检测到这种情况,我认为它会比现在更慢;)

我能看到的唯一方法是定义 foo 与您所做的类似,并通过使其迭代 foo 来制作反向映射来定义 bar ,但这对我来说没有多大意义,并且可能不适用于您的特定案子。

我认为您的案例是单元测试有用的一个很好的例子,那么为什么不写一个呢?

于 2013-02-04T20:03:25.420 回答
0

不,这是不可能的,因为这相当于停机问题,该问题在 1936 年被证明是无法解决的。

于 2013-02-17T13:36:30.157 回答