scala - 返回类型密封时的主观性检查

标签 scala pattern-matching algebraic-data-types non-exhaustive-patterns

Scala 可以在密封类型上的模式匹配不是详尽无遗时发出警告,但是我们可以检查函数是否在返回类型被密封时返回所有情况?例如,考虑以下 ADT

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

然后函数 f: Foo => String关于代数数据类型 Foo
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 
}

最佳答案

也许这不是真正的答案,但无论如何评论都太长了。

模式匹配和函数返回值是两件不同的事情。前者在类型级别上操作,后者在值级别上操作。当您在 Bar 上进行模式匹配时,您正在对类型进行模式匹配(就像例如 Int )。但是当你回来时Bar ,您正在返回 case 对象值(就像例如 42 )。

投影函数定义为:

For every member y of the codomain, there exists at least one member x of the domain, such that f(x) = y.



现在很容易理解为什么这个检查不可行/不可能。如果您的 Bar不是一个案例对象,而是一个类?例如。
final case class Bar(name: String, surname: String, age: Int)

您需要期望 Bar 的每个可能值要使用的(例如 name = "John", surname = "Smith", age = 42)。

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

正如我所说,这并不是真正的答案,但我想让您深入了解您要问的究竟是什么。 :) 也许有人用反射和/或宏编写了一些可以提供这种检查的东西,但据我所知。希望使用 Scala 3 枚举您永远不需要编写这样的函数。

关于scala - 返回类型密封时的主观性检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56152173/

相关文章:

C 符号类型和不相交的 union 类型?

pattern-matching - 您如何在 TypeScript 中模拟 ADT 和模式匹配?

haskell - 如何为 "from"编写 "to"和 "Add Void a === a"函数?

scala - 将play工程打包成jar/war文件

scala - 如何打印随机整数序列(scala)?

java - 模式匹配时如何忽略嵌套括号?

java - 如何解析特定的数据文件并对其内容进行聚类? java

scala - | + |是一个半群,为什么它需要一个monoid隐式解析

java - 用于自定义 "non-strict"排序的 Scala 或 java 数据结构

Swift Switch 访问 'case' 内的嵌套属性