Mar*_*lic 6 scala pattern-matching algebraic-data-types non-exhaustive-patterns
当在密封类型上的模式匹配不够详尽时,Scala会发出警告,但是当密封返回类型时,我们能否检查函数是否返回所有情况?例如,考虑以下ADT
sealed trait Foo
case object Bar extends Foo
case object Qux extends Foo
Run Code Online (Sandbox Code Playgroud)
然后f: Foo => String对代数数据类型起作用Foo
def f(x: Foo): String = x match {
case Bar => "bar"
}
Run Code Online (Sandbox Code Playgroud)
提出警告
match may not be exhaustive.
It would fail on the following input: Qux
def f(x: Foo) = x match {
Run Code Online (Sandbox Code Playgroud)
当返回类型为ADT时,是否可能引发类似的非耗尽警告,例如以下实现f: String => Foo:
def f(x: String): Foo = x match {
case "bar" => Bar
// warn because we never return Qux
}
Run Code Online (Sandbox Code Playgroud)
也许这并不是一个真正的答案,但是反正评论太长了。
模式匹配和函数返回值是两件事。前者在类型级别上操作,后者在值级别上操作。当您在上进行Bar模式匹配时,即在类型上进行模式匹配(例如Int)。但是,当您返回时Bar,您将返回case对象的值(例如42)。
形容词功能定义为:
对于共域的每个成员y,域中至少存在一个成员 x,使得f(x)= y。
现在,很容易看出为什么这种检查不可行/不可能。如果您Bar不是案例对象而是类,该怎么办?例如
final case class Bar(name: String, surname: String, age: Int)
Run Code Online (Sandbox Code Playgroud)
您需要期望使用所有可能的值Bar(例如,名称=“ John”,姓氏=“ Smith”,年龄= 42)。
当然,这不是您想要的。您所描述的是一个场景,其中每个子类型都只有一个居民,因为Bar和Qux基本上都是枚举,我可以理解为什么这样的检查对您有意义。但是对于每种(子)类型的任意数量的居民,通常必须实现它-需要验证共域包含至少一个类型的值Bar,至少一个类型的值,Qux等等。很有用。
就像我说的那样,这并不是真正的答案,但是我想让您深入了解您要问的是什么。:)也许有人用反射和/或宏写了一些东西,可以提供这种检查,但据我所知。希望使用Scala 3枚举,您将永远不需要编写这样的函数。
| 归档时间: |
|
| 查看次数: |
82 次 |
| 最近记录: |