汇总何时密封返回类型



当密封类型上的图案匹配时,Scala是否可以警告,但是,当返回类型密封时,我们可以检查功能是否返回所有情况?例如,考虑以下ADT

sealed trait Foo
case object Bar extends Foo
case object Qux extends Foo

然后在代数数据类型Foo

上函数f: Foo => String
def f(x: Foo): String = x match {
  case Bar => "bar"
}

提高警告

match may not be exhaustive.
It would fail on the following input: Qux
def f(x: Foo) = x match {

当返回类型是ADT时,例如在以下实现f: String => Foo时,可以提出类似的非避免警告:

def f(x: String): Foo = x match {
  case "bar" => Bar
  // warn because we never return Qux 
}

也许这不是一个真正的答案,但无论如何要发表评论。

模式匹配和函数返回值是两个不同的东西。前在 type 级别上运行,后者在 value 级别上进行操作。当您在Bar上进行模式匹配时,您的模式匹配类型(例如Int(。但是,当您返回Bar时,您将返回案例对象值(例如42(。

Suriftive函数定义为:

对于CODOMAN的每个成员 y ,至少存在一个成员 x 的域,因此 f(x(= y

现在很容易理解为什么此检查是不可行的/可能的。如果您的Bar不是案例对象,而是一类怎么办?例如

final case class Bar(name: String, surname: String, age: Int)

您需要期望使用Bar的所有可能值(例如名称=" John",姓氏=" Smith",年龄= 42(。

当然,这不是您的意图;您描述的是一个场景,每个子类型都有一个居民,因为BarQux基本上是枚举,我可以理解为什么这样的检查对您有意义。但是,必须针对每(sub(类型的任意居民数量的一般情况实现,它需要验证CODOMAIN至少包含一个Bar类型的值,至少一个值Qux等值的值听起来很有用。

正如我所说,这并不是一个真正的答案,但是我想让您了解您要问的确切的内容。:)也许有人用反思和/或宏来写了一些可以提供这样的支票的东西,但据我所知。希望使用Scala 3枚举,无论如何您都不需要编写这样的功能。

这是 @luismiguelmejíasuárez和@slouc建议的枚举示例,确实提供了案例耗尽:

enumeratum

import enumeratum._
sealed trait Foo extends EnumEntry
object Foo extends Enum[Foo] {
  val values = findValues
  case object Bar extends Foo
  case object Qux extends Foo  
}
Foo.withName("Qux")

Scala 3枚举

enum Foo {
  case Bar
  case Qux
}
Foo.enumValueNamed("Qux"))

即使使用参数化密封类型也可以正常工作。

相关内容

  • 没有找到相关文章

最新更新